Compare commits

..
157 Commits
Author SHA1 Message Date
Andre601 73d94e99e4 Fix length check 2023-04-03 21:26:09 +02:00
Andre601 389ed1df53 Improve HangarUploader 2023-04-03 21:22:01 +02:00
Andre601 5f4a07cb71 Remove cache 2023-04-03 20:59:23 +02:00
Andre601 b16f5e193c fix wrong path (hopefully) 2023-04-03 20:56:58 +02:00
Andre601 1c423e6cfa Add debug workflow 2023-04-03 20:52:10 +02:00
Andre601 a27dcd5248 Fix workflow file 2023-04-03 20:42:08 +02:00
Andre601 17bd1782fb Remove Paper module 2023-04-03 20:33:52 +02:00
Andre_601 96c44dafe2 Merge pull request #75 from Andre601/feature/hangar-automation
Automate Hangar publishing
2023-04-03 20:30:24 +02:00
Andre601 d4d9a7e3c5 Temporarely disable pr-build action 2023-04-03 20:29:32 +02:00
Andre601 9f0f7297f0 Final touches 2023-04-03 20:20:16 +02:00
Andre601 691cb14c63 Merge actions 2023-04-03 18:37:44 +02:00
Andre601 8670ea026e Pretty-print date (Also temp remove ViaVersion) 2023-04-03 17:40:09 +02:00
Andre601 27c019c00d Remove posting of the JSON Body 2023-04-03 17:25:33 +02:00
Andre601 d34ea9c2ad Further reduce dependency sizes 2023-04-03 17:21:47 +02:00
Andre601 74a61f2e09 Don't include ViaVersion dependency. 2023-04-03 16:33:36 +02:00
Andre601 5e550d5a7f Add JSON body for debugging 2023-04-03 15:13:11 +02:00
Andre601 b1180c0a8e Make plugin run on Folia 2023-04-03 01:38:40 +02:00
Andre601 fc4253acce Include body in error logging 2023-04-03 01:37:48 +02:00
Andre601 a4e2cc29d5 Add more logging messages 2023-04-03 01:24:19 +02:00
Andre601 95097a581a Fix jar names and add logback.xml 2023-04-03 01:10:33 +02:00
Andre601 aff3aefb72 Add mainClass attribute 2023-04-03 01:04:22 +02:00
Andre_601 089e56be70 Set working-directory 2023-04-03 00:58:05 +02:00
Andre601 e7b8f1a0dc First attempt at hangar automation... 2023-04-03 00:54:17 +02:00
Andre_601 a2252f55c4 Update hangar.yml 2023-04-03 00:53:24 +02:00
Andre_601 dcd6a1e867 try with just one file 2023-04-02 23:04:46 +02:00
Andre_601 24bf5193ff fix file names 2023-04-02 22:50:14 +02:00
Andre_601 2e0068115d Create hangar.yml 2023-04-02 22:43:29 +02:00
Andre_601 1accbfb5f0 Merge pull request #73 from Andre601/dependabot/pip/mkdocs-material-9.1.5
Bump mkdocs-material from 9.1.4 to 9.1.5
2023-03-31 18:10:44 +02:00
dependabot[bot] f0f520d12b Bump mkdocs-material from 9.1.4 to 9.1.5
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.1.4 to 9.1.5.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.1.4...9.1.5)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-31 16:03:53 +00:00
Andre601 3edef1c2e4 Bump API and plugin version for release 2023-03-29 18:41:31 +02:00
Andre_601 0c835da51a Merge pull request #72 from Andre601/dependabot/maven/velocity/org.bstats-bstats-velocity-3.0.2
Bump bstats-velocity from 3.0.1 to 3.0.2 in /velocity
2023-03-29 18:31:46 +02:00
dependabot[bot] 1dc937e7b6 Bump bstats-velocity from 3.0.1 to 3.0.2 in /velocity
Bumps [bstats-velocity](https://github.com/Bastian/bStats-Metrics) from 3.0.1 to 3.0.2.
- [Release notes](https://github.com/Bastian/bStats-Metrics/releases)
- [Commits](https://github.com/Bastian/bStats-Metrics/compare/v3.0.1...v3.0.2)

---
updated-dependencies:
- dependency-name: org.bstats:bstats-velocity
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-29 16:10:44 +00:00
Andre_601 8d63d92ab0 Merge pull request #71 from Andre601/dependabot/maven/paper/org.bstats-bstats-bukkit-3.0.2
Bump bstats-bukkit from 3.0.1 to 3.0.2 in /paper
2023-03-29 18:02:40 +02:00
dependabot[bot] 2ade1c2506 Bump bstats-bukkit from 3.0.1 to 3.0.2 in /paper
Bumps [bstats-bukkit](https://github.com/Bastian/bStats-Metrics) from 3.0.1 to 3.0.2.
- [Release notes](https://github.com/Bastian/bStats-Metrics/releases)
- [Commits](https://github.com/Bastian/bStats-Metrics/compare/v3.0.1...v3.0.2)

---
updated-dependencies:
- dependency-name: org.bstats:bstats-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-29 16:01:29 +00:00
Andre_601 c1b699aab7 Merge pull request #69 from Andre601/dependabot/maven/paper/com.viaversion-viaversion-api-4.6.2
Bump viaversion-api from 4.6.1 to 4.6.2 in /paper
2023-03-27 18:08:25 +02:00
dependabot[bot] 6d5fc7a697 Bump viaversion-api from 4.6.1 to 4.6.2 in /paper
Bumps viaversion-api from 4.6.1 to 4.6.2.

---
updated-dependencies:
- dependency-name: com.viaversion:viaversion-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-27 16:07:49 +00:00
Andre_601 a5acd73482 Add "Available on SpigotMC" badge 2023-03-24 23:03:16 +01:00
Andre_601 f1afcc0fd8 Merge pull request #68 from Andre601/dependabot/pip/mkdocs-material-9.1.4
Bump mkdocs-material from 9.1.3 to 9.1.4
2023-03-24 17:23:02 +01:00
dependabot[bot] 9922485c34 Bump mkdocs-material from 9.1.3 to 9.1.4
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.1.3 to 9.1.4.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.1.3...9.1.4)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-24 16:13:48 +00:00
Andre601 9ee543fe28 Use old Command handling for Spigot 2023-03-23 20:11:30 +01:00
Andre_601 da4eccdfcc remove spigot 2023-03-23 20:00:45 +01:00
Andre_601 89f5a45809 Use own fork for hangar badge 2023-03-23 18:24:25 +01:00
Andre601 29664fde70 Fix wrong artifact name 2023-03-23 16:50:39 +01:00
Andre601 40f362f1de Fix some PAPI placeholder stuff 2023-03-23 16:41:08 +01:00
Andre_601 07cef34a37 Merge pull request #50 from Andre601/feature/paper-plugin-support
First steps towards paper-plugin support
2023-03-23 16:22:43 +01:00
Andre601 afa80581e5 Bump version to 3.0.0-b1 2023-03-23 16:22:15 +01:00
Andre601 db2366e2ce Merge branch 'master' into feature/paper-plugin-support 2023-03-23 16:18:46 +01:00
Andre601 b54151813f Update release action to allow beta-releases 2023-03-23 16:14:59 +01:00
Andre601 2be041a613 Fix wrong path (Also ignore other jobs for now 2023-03-23 16:04:33 +01:00
Andre601 86411571ef Test out pre-release detection 2023-03-23 15:52:32 +01:00
Andre_601 d80236fef8 Remove paper module 2023-03-21 02:59:32 +01:00
Andre601 fe6fae58e3 Add Profiles example and fix badges width 2023-03-21 02:54:36 +01:00
Andre_601 b2e2b18d33 Add Pip (Python) to dependabot checks 2023-03-21 02:20:51 +01:00
Andre_601 d8e54c7ff0 Remove mike from requirements.txt 2023-03-21 02:16:53 +01:00
Andre_601 f0743d691f Merge pull request #66 from Andre601/dependabot/maven/spigot/org.apache.maven.plugins-maven-shade-plugin-3.4.1
Bump maven-shade-plugin from 3.4.0 to 3.4.1 in /spigot
2023-03-20 17:10:25 +01:00
Andre_601 4b68253c7d Merge pull request #65 from Andre601/dependabot/maven/spigot/org.apache.maven.plugins-maven-compiler-plugin-3.11.0
Bump maven-compiler-plugin from 3.10.1 to 3.11.0 in /spigot
2023-03-20 17:10:12 +01:00
Andre_601 d1cee68355 Merge pull request #64 from Andre601/dependabot/maven/spigot/me.clip-placeholderapi-2.11.3
Bump placeholderapi from 2.11.2 to 2.11.3 in /spigot
2023-03-20 17:09:38 +01:00
Andre_601 07d3ea088a Merge pull request #63 from Andre601/dependabot/maven/paper/me.clip-placeholderapi-2.11.3
Bump placeholderapi from 2.11.2 to 2.11.3 in /paper
2023-03-20 17:09:23 +01:00
dependabot[bot] 912fb967fb Bump maven-shade-plugin from 3.4.0 to 3.4.1 in /spigot
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.4.0 to 3.4.1.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.4.0...maven-shade-plugin-3.4.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 16:07:52 +00:00
dependabot[bot] d960644cc1 Bump maven-compiler-plugin from 3.10.1 to 3.11.0 in /spigot
Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.10.1 to 3.11.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.10.1...maven-compiler-plugin-3.11.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 16:07:39 +00:00
dependabot[bot] 34908b4123 Bump placeholderapi from 2.11.2 to 2.11.3 in /spigot
Bumps placeholderapi from 2.11.2 to 2.11.3.

---
updated-dependencies:
- dependency-name: me.clip:placeholderapi
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 16:07:31 +00:00
dependabot[bot] 00466f1ffb Bump placeholderapi from 2.11.2 to 2.11.3 in /paper
Bumps placeholderapi from 2.11.2 to 2.11.3.

---
updated-dependencies:
- dependency-name: me.clip:placeholderapi
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 16:07:22 +00:00
Andre601 d05527634d Add clearCache subcommand.
Also, add convenience methods for sending prefixed messages.
2023-03-20 15:09:02 +01:00
Andre601 6e017219b4 Add ViaVersion as soft-depend 2023-03-20 14:33:31 +01:00
Andre601 8fa66867bc Load PaperPingEvent and also improve PAPI placeholders 2023-03-18 17:07:28 +01:00
Andre601 1df167b66a Merge branch 'master' into feature/paper-plugin-support 2023-03-18 16:13:51 +01:00
Andre601 ffee02095f Remove unused import 2023-03-18 16:07:48 +01:00
Andre601 0fc7c7f047 Bump ProtocolLib version 2023-03-18 15:58:07 +01:00
Andre_601 c8ae03da16 Merge pull request #62 from Andre601/dependabot/github_actions/actions/cache-3
Bump actions/cache from 2 to 3
2023-03-17 18:06:33 +01:00
dependabot[bot] dc4165465e Bump actions/cache from 2 to 3
Bumps [actions/cache](https://github.com/actions/cache) from 2 to 3.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v2...v3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-17 16:01:55 +00:00
Andre601 05c32cd721 [Docs] Update badges to v3 2023-03-17 14:43:36 +01:00
Andre601 ccd326f036 Add ViaVersion to dependencies list 2023-03-17 14:31:03 +01:00
Andre601 e9117c8040 Revert docs to MkDocs only
(Mike kinda sucks, ngl)
2023-03-17 14:24:43 +01:00
Andre601 116714f9a4 Try fixing page deploy. 2023-03-17 01:30:27 +01:00
Andre601 06f025c50e Add missing page to nav 2023-03-17 01:26:57 +01:00
Andre601 25787e8c51 Include 1.19.4 in supported versions 2023-03-17 01:22:40 +01:00
Andre601 741ca73c62 Add PlaceholderAPI placeholders 2023-03-17 01:22:02 +01:00
Andre601 50944717ea Merge docs update into releas action 2023-03-17 01:01:21 +01:00
Andre_601 89d2d04c12 Merge pull request #61 from Andre601/dependabot/maven/spigot/net.kyori-adventure-platform-bukkit-4.3.0
Bump adventure-platform-bukkit from 4.2.0 to 4.3.0 in /spigot
2023-03-16 17:07:19 +01:00
dependabot[bot] 2aa53c556a Bump adventure-platform-bukkit from 4.2.0 to 4.3.0 in /spigot
Bumps [adventure-platform-bukkit](https://github.com/KyoriPowered/adventure-platform) from 4.2.0 to 4.3.0.
- [Release notes](https://github.com/KyoriPowered/adventure-platform/releases)
- [Commits](https://github.com/KyoriPowered/adventure-platform/compare/v4.2.0...v4.3.0)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-platform-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-16 16:05:18 +00:00
Andre_601 7eb67c1571 Merge pull request #58 from Andre601/dependabot/maven/core/net.kyori-adventure-api-4.13.0
Bump adventure-api from 4.12.0 to 4.13.0 in /core
2023-03-15 17:14:39 +01:00
Andre_601 e6ebf0964b Merge pull request #60 from Andre601/dependabot/maven/core/net.kyori-adventure-text-serializer-legacy-4.13.0
Bump adventure-text-serializer-legacy from 4.12.0 to 4.13.0 in /core
2023-03-15 17:05:33 +01:00
Andre_601 2f7bbe8bae Merge pull request #59 from Andre601/dependabot/maven/core/net.kyori-adventure-text-minimessage-4.13.0
Bump adventure-text-minimessage from 4.12.0 to 4.13.0 in /core
2023-03-15 17:05:15 +01:00
dependabot[bot] cc3e75f41b Bump adventure-text-serializer-legacy from 4.12.0 to 4.13.0 in /core
Bumps [adventure-text-serializer-legacy](https://github.com/KyoriPowered/adventure) from 4.12.0 to 4.13.0.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.12.0...v4.13.0)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-text-serializer-legacy
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-15 16:03:13 +00:00
dependabot[bot] 7706dd245f Bump adventure-text-minimessage from 4.12.0 to 4.13.0 in /core
Bumps [adventure-text-minimessage](https://github.com/KyoriPowered/adventure) from 4.12.0 to 4.13.0.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.12.0...v4.13.0)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-text-minimessage
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-15 16:03:06 +00:00
dependabot[bot] d4018ff666 Bump adventure-api from 4.12.0 to 4.13.0 in /core
Bumps [adventure-api](https://github.com/KyoriPowered/adventure) from 4.12.0 to 4.13.0.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.12.0...v4.13.0)

---
updated-dependencies:
- dependency-name: net.kyori:adventure-api
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-15 16:03:01 +00:00
Andre_601 4c7a2ca94d Update wiki links to link to latest 2023-03-13 01:35:17 +01:00
Andre_601 21632711ea Merge pull request #57 from Andre601/dependabot/maven/core/com.github.ben-manes.caffeine-caffeine-3.1.5
Bump caffeine from 3.1.4 to 3.1.5 in /core
2023-03-06 17:15:29 +01:00
dependabot[bot] e82ed84c11 Bump caffeine from 3.1.4 to 3.1.5 in /core
Bumps [caffeine](https://github.com/ben-manes/caffeine) from 3.1.4 to 3.1.5.
- [Release notes](https://github.com/ben-manes/caffeine/releases)
- [Commits](https://github.com/ben-manes/caffeine/compare/v3.1.4...v3.1.5)

---
updated-dependencies:
- dependency-name: com.github.ben-manes.caffeine:caffeine
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-06 16:12:19 +00:00
Andre601 1f44b34dd2 Update workflow titles 2023-03-03 21:05:36 +01:00
Andre601 b7b6d8b82b Make dev a default for mkdocs-material 2023-03-03 20:56:50 +01:00
Andre601 53e270b183 Try dev build of Mike from GitHub 2023-03-03 17:28:49 +01:00
Andre601 f633bb393e Revert "Make fetch-depht 1"
This reverts commit 42907c7f74.
2023-03-03 17:27:49 +01:00
Andre601 41ac71e346 Revert "Make fetch-depth 1"
This reverts commit e04b9b4a09.
2023-03-03 17:27:35 +01:00
Andre_601 e04b9b4a09 Make fetch-depth 1 2023-03-02 01:19:56 +01:00
Andre_601 42907c7f74 Make fetch-depht 1 2023-03-02 01:19:33 +01:00
Andre_601 69bf90c20f Make dev the default branch 2023-03-01 13:58:27 +01:00
Andre601 b2f70b605c Update CSS stuff 2023-03-01 03:35:52 +01:00
Andre601 fb5e4b57bc Create versioned docs 2023-03-01 02:33:29 +01:00
Andre601 49c17d941a Fix wrong workflow file names 2023-03-01 00:05:42 +01:00
Andre601 ec6b852497 typo 2023-03-01 00:03:03 +01:00
Andre_601 9bd2c4b8d5 Merge pull request #54 from Andre601/feature/versioned-docs
Set up versioned docs
2023-02-28 23:01:11 +01:00
Andre_601 57bb677578 Merge pull request #56 from Andre601/dependabot/maven/velocity/org.apache.maven.plugins-maven-compiler-plugin-3.11.0
Bump maven-compiler-plugin from 3.10.1 to 3.11.0 in /velocity
2023-02-28 17:07:00 +01:00
Andre_601 40c4726fd6 Merge pull request #55 from Andre601/dependabot/maven/paper/org.apache.maven.plugins-maven-compiler-plugin-3.11.0
Bump maven-compiler-plugin from 3.10.1 to 3.11.0 in /paper
2023-02-28 17:06:48 +01:00
dependabot[bot] c1eefbe114 Bump maven-compiler-plugin from 3.10.1 to 3.11.0 in /velocity
Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.10.1 to 3.11.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.10.1...maven-compiler-plugin-3.11.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 16:04:25 +00:00
dependabot[bot] 082345fb66 Bump maven-compiler-plugin from 3.10.1 to 3.11.0 in /paper
Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.10.1 to 3.11.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.10.1...maven-compiler-plugin-3.11.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 16:04:19 +00:00
Andre601 1bedc472b3 Extend the theme 2023-02-28 03:06:18 +01:00
Andre601 aa9d6ff7d2 Set up versioned docs 2023-02-28 02:35:47 +01:00
Andre601 5e4fc3d69c Smaller typo fix in api docs 2023-02-28 02:13:10 +01:00
Andre_601 b429e75797 Merge pull request #53 from Andre601/dependabot/maven/bungeecord/org.apache.maven.plugins-maven-compiler-plugin-3.11.0
Bump maven-compiler-plugin from 3.10.1 to 3.11.0 in /bungeecord
2023-02-27 17:13:39 +01:00
Andre_601 c2eacf716f Merge pull request #52 from Andre601/dependabot/maven/core/org.apache.maven.plugins-maven-compiler-plugin-3.11.0
Bump maven-compiler-plugin from 3.10.1 to 3.11.0 in /core
2023-02-27 17:13:28 +01:00
dependabot[bot] aca52b528d Bump maven-compiler-plugin from 3.10.1 to 3.11.0 in /bungeecord
Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.10.1 to 3.11.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.10.1...maven-compiler-plugin-3.11.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-27 16:13:20 +00:00
dependabot[bot] cd1469c554 Bump maven-compiler-plugin from 3.10.1 to 3.11.0 in /core
Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.10.1 to 3.11.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.10.1...maven-compiler-plugin-3.11.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-27 16:12:46 +00:00
Andre601 ce4347ca1e Improve CommandHandler 2023-02-23 01:51:04 +01:00
Andre601 acc59e0af7 Prepare docs for next ASL API. 2023-02-23 00:49:14 +01:00
Andre601 099abcda67 Make sure paper-plugin loads after PlaceholderAPI 2023-02-23 00:37:07 +01:00
Andre601 2ced4db199 Small formatting for actions 2023-02-22 22:27:18 +01:00
Andre601 4f7c16ae5a Use PaperMC Maven repo 2023-02-20 23:30:19 +01:00
Andre_601 06739bb68e Merge pull request #51 from Andre601/dependabot/maven/core/com.github.ben-manes.caffeine-caffeine-3.1.4
Bump caffeine from 3.1.3 to 3.1.4 in /core
2023-02-20 17:13:37 +01:00
dependabot[bot] d1c9ab5b82 Bump caffeine from 3.1.3 to 3.1.4 in /core
Bumps [caffeine](https://github.com/ben-manes/caffeine) from 3.1.3 to 3.1.4.
- [Release notes](https://github.com/ben-manes/caffeine/releases)
- [Commits](https://github.com/ben-manes/caffeine/compare/v3.1.3...v3.1.4)

---
updated-dependencies:
- dependency-name: com.github.ben-manes.caffeine:caffeine
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-20 16:10:36 +00:00
Andre601 d06f767e51 Rename to BukkitPlayerPlaceholders for clarity 2023-02-20 14:10:58 +01:00
Andre601 02e0821bd0 Merge CmdAdvancedServerList instances into one 2023-02-20 14:07:25 +01:00
Andre601 981d4e8146 First steps towards paper-plugin support 2023-02-20 01:53:02 +01:00
Andre_601 05667c0f87 Update MODRINTH.md 2023-02-13 22:44:54 +01:00
Andre_601 54f0f59925 Updated badges to v3 2023-02-13 22:41:49 +01:00
Andre_601 de2c8a7547 Merge pull request #49 from Andre601/dependabot/maven/velocity/org.bstats-bstats-velocity-3.0.1
Bump bstats-velocity from 3.0.0 to 3.0.1 in /velocity
2023-02-13 17:14:04 +01:00
Andre_601 50c31a3348 Merge pull request #48 from Andre601/dependabot/maven/paper/org.bstats-bstats-bukkit-3.0.1
Bump bstats-bukkit from 3.0.0 to 3.0.1 in /paper
2023-02-13 17:13:54 +01:00
Andre_601 93e94aa9d3 Merge pull request #47 from Andre601/dependabot/maven/spigot/org.bstats-bstats-bukkit-3.0.1
Bump bstats-bukkit from 3.0.0 to 3.0.1 in /spigot
2023-02-13 17:13:42 +01:00
dependabot[bot] 1f71aeb7e5 Bump bstats-velocity from 3.0.0 to 3.0.1 in /velocity
Bumps [bstats-velocity](https://github.com/Bastian/bStats-Metrics) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/Bastian/bStats-Metrics/releases)
- [Commits](https://github.com/Bastian/bStats-Metrics/compare/v3.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: org.bstats:bstats-velocity
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-13 16:13:04 +00:00
dependabot[bot] 5d01adfa49 Bump bstats-bukkit from 3.0.0 to 3.0.1 in /paper
Bumps [bstats-bukkit](https://github.com/Bastian/bStats-Metrics) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/Bastian/bStats-Metrics/releases)
- [Commits](https://github.com/Bastian/bStats-Metrics/compare/v3.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: org.bstats:bstats-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-13 16:13:02 +00:00
dependabot[bot] da7e3eca09 Bump bstats-bukkit from 3.0.0 to 3.0.1 in /spigot
Bumps [bstats-bukkit](https://github.com/Bastian/bStats-Metrics) from 3.0.0 to 3.0.1.
- [Release notes](https://github.com/Bastian/bStats-Metrics/releases)
- [Commits](https://github.com/Bastian/bStats-Metrics/compare/v3.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: org.bstats:bstats-bukkit
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-13 16:12:48 +00:00
Andre_601 66b305bbea Merge pull request #46 from Andre601/dependabot/maven/core/com.github.ben-manes.caffeine-caffeine-3.1.3
Bump caffeine from 3.1.2 to 3.1.3 in /core
2023-02-10 17:16:03 +01:00
dependabot[bot] 3c1abf4f3a Bump caffeine from 3.1.2 to 3.1.3 in /core
Bumps [caffeine](https://github.com/ben-manes/caffeine) from 3.1.2 to 3.1.3.
- [Release notes](https://github.com/ben-manes/caffeine/releases)
- [Commits](https://github.com/ben-manes/caffeine/compare/v3.1.2...v3.1.3)

---
updated-dependencies:
- dependency-name: com.github.ben-manes.caffeine:caffeine
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-10 16:07:29 +00:00
Andre_601 856be1e32e Update index.md 2023-02-03 22:33:28 +01:00
Andre601 5303bb00a0 More docs corrections 2023-02-01 15:55:19 +01:00
Andre601 9b43428e5d Another fix for changelog... 2023-02-01 15:47:18 +01:00
Andre601 d34d926f9a Fix wrong version in api changelog 2023-02-01 15:46:57 +01:00
Andre601 844279b32d Rename the other Placeholder classes too. 2023-02-01 15:38:00 +01:00
Andre601 5916e9b495 Version was already bumped... whoops 2023-02-01 15:31:56 +01:00
Andre_601 72384488d8 Merge pull request #45 from Andre601/feature/events
Add PreServerListSetEvent
2023-02-01 15:29:38 +01:00
Andre601 11a8b07f32 Bump version 2023-02-01 15:24:13 +01:00
Andre601 cd7dfc9c15 Rename to resolve 2023-01-31 18:12:43 +01:00
Andre601 c715ed6163 Make values of Expression final 2023-01-31 18:12:21 +01:00
Andre601 5a35ebbef4 Trim left and right string to avoid comparison issues 2023-01-31 17:17:10 +01:00
Andre601 830eee5da3 Fix missing favicon from resolver. 2023-01-28 23:22:08 +01:00
Andre601 09b845e86e Changes 2023-01-28 23:13:41 +01:00
Andre601 a2bdd5c4e5 Add changelog file 2023-01-27 14:59:12 +01:00
Andre601 a72c0d326a Update to latest API changes 2023-01-27 00:59:29 +01:00
Andre601 40ef2e35d4 Make GenericPlayer.getVersion VelocityPlayer only 2023-01-25 22:13:39 +01:00
Andre601 8422d6d2de Minor doc improvements 2023-01-25 16:19:43 +01:00
Andre601 4683dab513 limit motd in ProfileEntry.Builder directly 2023-01-25 16:15:07 +01:00
Andre601 d5947b20e5 Update docs 2023-01-25 01:11:45 +01:00
Andre601 147f01dd1b Rename GenericProfileEntryEvent to GenericServerListEvent 2023-01-25 00:29:07 +01:00
Andre601 a6eddb3828 Remove unused method in ComponentParser 2023-01-25 00:05:09 +01:00
Andre601 41e11f79cc Move ProfileEntry completely. 2023-01-25 00:01:51 +01:00
Andre601 66597ce7fa Add PreServerListSetEvent 2023-01-24 23:38:23 +01:00
Andre_601 77f17b202c Update MODRINTH.md 2023-01-23 21:28:57 +01:00
89 changed files with 2051 additions and 2223 deletions

No files matched your search

+13 -17
View File
@@ -4,19 +4,19 @@ AdvancedServerList is a plugin that allowys you to customize your server's MOTD,
## Supported Platforms
<a href="https://www.spigotmc.org" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/spigot_vector.svg" width="64" alt="platform-spigot" title="Tested on Spigot">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/spigot_vector.svg" width="64" alt="platform-spigot" title="Tested on Spigot">
</a>
<a href="https://papermc.io" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/paper_vector.svg" width="64" alt="platform-paper" title="Tested on Paper">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/paper_vector.svg" width="64" alt="platform-paper" title="Tested on Paper">
</a>
<a href="https://www.spigotmc.org" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/bungeecord_vector.svg" width="64" alt="platform-bungeecord" title="Tested on BungeeCord">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/bungeecord_vector.svg" width="64" alt="platform-bungeecord" title="Tested on BungeeCord">
</a>
<a href="https://www.papermc.io" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/waterfall_vector.svg" width="64" alt="platform-waterfall" title="Tested on Waterfall">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/waterfall_vector.svg" width="64" alt="platform-waterfall" title="Tested on Waterfall">
</a>
<a href="https://velocitypowered.com" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/velocity_vector.svg" width="64" alt="platform-velocity" title="Tested on Velocity">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/velocity_vector.svg" width="64" alt="platform-velocity" title="Tested on Velocity">
</a>
## What is a Server List Profile?
@@ -61,29 +61,25 @@ You can disable this in the global bStats config file located in `/plugins/bstat
## Screenshots
<a href="https://modrinth.com/plugin/advancedserverlist/gallery" target="_blank">
<img src="https://raw.githubusercontent.com/intergrav/devins-badges/v2/assets/cozy/documentation/modrinth-gallery_vector.svg" width="208" alt="gallery" title="Check out the Gallery">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/documentation/modrinth-gallery_vector.svg" width="208" alt="gallery" title="Check out the Gallery">
</a>
## Support
<a href="https://discord.gg/6dazXp6" target="_blank">
<img src="https://raw.githubusercontent.com/intergrav/devins-badges/v2/assets/minimal/social/discord-singular_vector.svg" width="64" alt="discord" title="Join my Discord Server">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/social/discord-singular_vector.svg" width="64" alt="discord" title="Join my Discord Server">
</a>
<a href="https://app.revolt.chat/invite/74TpERXA" target="_blank">
<img src="https://raw.githubusercontent.com/intergrav/devins-badges/v2/assets/minimal/social/revolt-singular_vector.svg" width="64" alt="revolt" title="Join my Revolt Server">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/social/revolt-singular_vector.svg" width="64" alt="revolt" title="Join my Revolt Server">
</a>
<a href="https://blobfox.coffee/@andre_601" target="_blank">
<img src="https://raw.githubusercontent.com/intergrav/devins-badges/v2/assets/minimal/social/mastodon-singular_vector.svg" width="64" alt="revolt" title="Chat with me on Mastodon">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/social/mastodon-singular_vector.svg" width="64" alt="revolt" title="Chat with me on Mastodon">
</a>
<!-- Links -->
[profiles]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles
[conditions]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#conditions
[placeholders]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#placeholders
[minimessage]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#minimessage
[placeholderapi]: https://www.spigotmc.org/resources/6245/
[modrinth]: https://modrinth.com/plugin/advancedserverlist
[profiles]: https://andre601.ch/AdvancedServerList/profiles
[conditions]: https://andre601.ch/AdvancedServerList/profiles/#conditions
[placeholders]: https://andre601.ch/AdvancedServerList/profiles/placeholders
[minimessage]: https://andre601.ch/AdvancedServerList/profiles/formatting
[protocollib]: https://www.spigotmc.org/resources/1997/
[placeholderapi]: https://www.spigotmc.org/resources/6245/
+8
View File
@@ -48,3 +48,11 @@ updates:
labels:
- 'Type: Update Dependency'
- 'Target: GitHub Action'
- package-ecosystem: pip
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
labels:
- 'Type: Update Dependency'
- 'Target: MkDocs'
+12 -7
View File
@@ -1,14 +1,17 @@
name: Deploy Site
name: 'Deploy Site (Push)'
on:
workflow_dispatch:
push:
paths:
- 'docs/**'
- 'mkdocs.yml'
- 'mkdocs-theme/**'
- 'requirements.txt'
branches:
- master
tags-ignore:
- '**'
- '**'
jobs:
build:
@@ -18,13 +21,15 @@ jobs:
- name: Set up Python 3.7
uses: actions/setup-python@v4
with:
python-version: 3.7
python-version: 3.x
- name: Create/Get Cache
uses: actions/cache@v3
with:
key: ${{ github.ref }}
path: .cache
- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools
python -m pip install -r requirements.txt
- name: Deploy Files
run: |
git config user.name "github-actions[bot]"
git config user.email "actions@github.com"
mkdocs gh-deploy --force
run: mkdocs gh-deploy --force
+88
View File
@@ -0,0 +1,88 @@
name: 'Build PR changes'
on:
pull_request_target:
types:
- opened
- reopened
- synchronize
paths:
- 'bukkit/src/**'
- 'bungeecord/src/**'
- 'core/src/**'
- 'velocity/src/**'
concurrency: 'pr-preview'
jobs:
buildJars:
name: 'Build Jars from Pull request'
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
uses: actions/checkout@v3
- name: 'Setup Java 16'
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: '16'
cache: 'maven'
- name: 'Build Jar files'
run: mvn clean install
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: asl-files
path: '*/target/AdvancedServerList-*.jar'
if-no-files-found: error
updateCommentSuccess:
name: 'Create or update Comment (On Success).'
needs: [buildJars]
if: success()
runs-on: ubuntu-latest
steps:
- name: Find comment
uses: peter-evans/find-comment@v2
id: find-comment
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
- name: Update Comment
uses: peter-evans/create-or-update-comment@v2
with:
body: |-
## Build Preview
Below is a URL to the Jar files made using this Pull request.
Please note that artifacts build by this GitHub Action only exist for at most 90 days since last run!
| Name | Link |
|-----------|-------------------------------------------------------------------------------------|
| Commit | ${{ github.event.pull_request.head.sha }} |
| Logs | ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} |
| Jar Files | <!-- What can I put here? --> |
UpdateCommentFailure:
name: 'Create or update Comment (On Success).'
needs: [buildJars]
if: failure()
runs-on: ubuntu-latest
steps:
- name: Find comment
uses: peter-evans/find-comment@v2
id: find-comment
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
- name: Update Comment
uses: peter-evans/create-or-update-comment@v2
with:
body: |-
## Build Preview
There was an issue generating the Jar files from your Pull request.
Please review the logs linked below for further information.
| Name | Link |
|--------|-------------------------------------------------------------------------------------|
| Commit | ${{ github.event.pull_request.head.sha }} |
| Logs | ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} |
+66 -40
View File
@@ -13,8 +13,16 @@ on:
jobs:
buildJars:
runs-on: ubuntu-latest
outputs:
plugin_release: ${{ steps.github-release.outputs.PLUGIN_RELEASE }}
steps:
- uses: actions/checkout@v3
- name: Checkout Repository
uses: actions/checkout@v3
- name: Get Version from Release
id: github-release
run: |
version=$(echo ${{ github.event.release.tag_name }} | cut -d'v' -f2)
echo "PLUGIN_RELEASE=$version" >> $GITHUB_OUTPUT
- name: Set up JDK 1.16
uses: actions/setup-java@v3
with:
@@ -23,32 +31,13 @@ jobs:
cache: 'maven'
- name: Build Jar files
run: mvn clean install
- name: Save BungeeCord Jar file
- name: Save All files
uses: actions/upload-artifact@v3
with:
name: asl-bungeecord
path: bungeecord/target/AdvancedServerList-*.jar
if-no-files-found: error
retention-days: 1
- name: Save Paper Jar file
uses: actions/upload-artifact@v3
with:
name: asl-paper
path: paper/target/AdvancedServerList-*.jar
if-no-files-found: error
retention-days: 1
- name: Save Spigot Jar file
uses: actions/upload-artifact@v3
with:
name: asl-spigot
path: spigot/target/AdvancedServerList-*.jar
if-no-files-found: error
retention-days: 1
- name: Save Velocity Jar file
uses: actions/upload-artifact@v3
with:
name: asl-velocity
path: velocity/target/AdvancedServerList-*.jar
name: asl-files
path: |
*/target/AdvancedServerList-*.jar
hangar-uploader/target/HangarUploader.jar
if-no-files-found: error
retention-days: 1
publish:
@@ -61,12 +50,11 @@ jobs:
loaders: |
bungeecord
waterfall
- platforms: Paper
directory: paper
loaders: paper
- platforms: Spigot
directory: spigot
loaders: spigot
- platforms: Spigot, Paper
directory: bukkit
loaders: |
spigot
paper
- platforms: Velocity
directory: velocity
loaders: velocity
@@ -76,18 +64,13 @@ jobs:
- name: Get Jar files
uses: actions/download-artifact@v3
with:
name: asl-${{ matrix.directory }}
path: ${{ matrix.directory }}/target
- name: Get Version
id: github-release
run: |
version=$(echo ${{ github.event.release.tag_name }} | cut -d'v' -f2)
echo "PLUGIN_RELEASE=$version" >> $GITHUB_OUTPUT
- name: Upload AdvancedServerList (${{ matrix.loaders }}) to GitHub and Modrinth
name: asl-files
- name: Upload AdvancedServerList v${{ needs.buildJars.outputs.plugin_release }} (${{ matrix.loaders }}) to GitHub and Modrinth
if: '!github.event.release.prerelease'
uses: Kir-Antipov/mc-publish@v3.2
with:
name: ${{ github.event.release.tag_name }} (${{ matrix.platforms }})
version: ${{ steps.github-release.outputs.PLUGIN_RELEASE }}
version: ${{ needs.buildJars.outputs.plugin_release }}
version-type: release
files: ${{ matrix.directory}}/target/AdvancedServerList-*.jar
files-secondary: ""
@@ -98,8 +81,51 @@ jobs:
1.19.1
1.19.2
1.19.3
1.19.4
java: 16
modrinth-id: xss83sOY
modrinth-featured: false
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload AdvancedServerList v${{ needs.buildJars.outputs.plugin_release }} (${{ matrix.loaders }}) to GitHub and Modrinth [Pre-Release]
if: 'github.event.release.prerelease'
uses: Kir-Antipov/mc-publish@v3.2
with:
name: ${{ github.event.release.tag_name }} (${{ matrix.platforms }})
version: ${{ needs.buildJars.outputs.plugin_release }}
version-type: beta
files: ${{ matrix.directory }}/target/AdvancedServerList-*.jar
files-secondary: ""
loaders: ${{ matrix.loaders }}
version-resolver: releases
game-versions: |
1.19
1.19.1
1.19.2
1.19.3
1.19.4
java: 16
modrinth-id: xss83sOY
modrinth-featured: false
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
publishHangar:
needs: [buildJars]
runs-on: ubuntu-latest
steps:
- name: Set up JDK 1.16
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '16'
- name: Download Release Assets
uses: actions/download-artifact@v3
with:
name: asl-files
- name: Move HangarUploader.jar
working-directory: hangar-uploader/target/
run: mv HangarUploader.jar ../../
- name: Execute HangarUploader.jar
run: java -jar HangarUploader.jar ${{ secrets.HANGAR_TOKEN }} ${{ needs.buildJars.outputs.plugin_release }} ${{ github.event.release.prerelease }}
env:
GITHUB_RELEASE_BODY: ${{ github.event.release.body }}
+25 -13
View File
@@ -1,26 +1,36 @@
# AdvancedServerList
<a href="https://modrinth.com/plugin/advancedserverlist" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/cozy/available/modrinth_vector.svg" height="64" align="right" alt="modrinth" title="Available on Modrinth">
</a>
AdvancedServerList is a plugin that allowys you to customize your server's MOTD, favicon, Player count text and player count hover displayed in a player's multiplayer server list based on conditions and priorities.
## Downloads
<a href="https://modrinth.com/plugin/advancedserverlist" target="_blank">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact/available/modrinth_vector.svg" height="46" alt="modrinth" title="Available on Modrinth">
</a>
<br>
<a href="https://hangar.papermc.io/Andre_601/AdvancedServerList" target="_blank">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact/available/hangar_vector.svg" height="46" alt="hangar" title="Available on Hangar">
</a>
<br>
<a href="https://www.spigotmc.org/resources/102910" target="_blank">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@b9ff12b/assets/compact/available/spigot_vector.svg" height="46" alt="spigot" title="Available on SpigotMC">
</a>
## Supported Platforms
<a href="https://www.spigotmc.org" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/spigot_vector.svg" height="64" alt="platform-spigot" title="Tested on Spigot">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/supported/spigot_vector.svg" height="64" alt="platform-spigot" title="Tested on Spigot">
</a>
<a href="https://papermc.io" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/paper_vector.svg" height="64" alt="platform-paper" title="Tested on Paper">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/supported/paper_vector.svg" height="64" alt="platform-paper" title="Tested on Paper">
</a>
<a href="https://www.spigotmc.org" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/bungeecord_vector.svg" height="64" alt="platform-bungeecord" title="Tested on BungeeCord">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/supported/bungeecord_vector.svg" height="64" alt="platform-bungeecord" title="Tested on BungeeCord">
</a>
<a href="https://www.papermc.io" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/waterfall_vector.svg" height="64" alt="platform-waterfall" title="Tested on Waterfall">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/supported/waterfall_vector.svg" height="64" alt="platform-waterfall" title="Tested on Waterfall">
</a>
<a href="https://velocitypowered.com" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/velocity_vector.svg" height="64" alt="platform-velocity" title="Tested on Velocity">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/supported/velocity_vector.svg" height="64" alt="platform-velocity" title="Tested on Velocity">
</a>
## What is a Server List Profile?
@@ -55,9 +65,10 @@ Only certain options are usable for each option. As an example does motd support
## Dependencies
| Dependency | Platforms | Required? |
| ---------------- | ------------- | --------- |
|------------------|---------------|-----------|
| [ProtocolLib] | Spigot | Yes |
| [PlaceholderAPI] | Spigot, Paper | No |
| [ViaVersion] | Spigot, Paper | No |
## Statistics
@@ -71,18 +82,18 @@ You can disable this in the global bStats config file located in `/plugins/bstat
## Screenshots
<a href="https://modrinth.com/plugin/advancedserverlist/gallery" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/cozy/documentation/modrinth-gallery_vector.svg" height="64" alt="gallery" title="Check out the Gallery">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/documentation/modrinth-gallery_vector.svg" height="64" alt="gallery" title="Check out the Gallery">
</a>
## Support
<a href="https://discord.gg/6dazXp6" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/social/discord-singular_vector.svg" height="64" alt="discord" title="Join my Discord Server">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/social/discord-singular_vector.svg" height="64" alt="discord" title="Join my Discord Server">
</a>
<a href="https://app.revolt.chat/invite/74TpERXA" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/social/revolt-singular_vector.svg" height="64" alt="revolt" title="Join my Revolt Server">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/social/revolt-singular_vector.svg" height="64" alt="revolt" title="Join my Revolt Server">
</a>
<a href="https://blobfox.coffee/@andre_601" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/social/mastodon-singular_vector.svg" height="64" alt="mastodon" title="Chat with me on Mastodon">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/social/mastodon-singular_vector.svg" height="64" alt="mastodon" title="Chat with me on Mastodon">
</a>
<!-- Links -->
@@ -95,6 +106,7 @@ You can disable this in the global bStats config file located in `/plugins/bstat
[protocollib]: https://www.spigotmc.org/resources/1997/
[placeholderapi]: https://www.spigotmc.org/resources/6245/
[viaversion]: https://www.spigotmc.org/resources/19254/
[bstats]: https://bstats.org
[bstats-bungee]: https://bstats.org/plugin/bungeecord/AdvancedServerList/15585
-59
View File
@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ MIT License
~
~ Copyright (c) 2022-2023 Andre_601
~
~ 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.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>parent</artifactId>
<groupId>ch.andre601.advancedserverlist</groupId>
<version>parent</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>api</artifactId>
<packaging>jar</packaging>
<version>${plugin.version}</version>
<description>${plugin.description}</description>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<finalName>AdvancedServerList-API-${plugin.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
</plugin>
</plugins>
</build>
</project>
@@ -1,98 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.api;
import ch.andre601.advancedserverlist.api.internal.CheckUtil;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
* Core class of the API for AdvancedServerList.
* <br>Use {@link #get() get()} to retrieve the instance currently used.
*/
public class AdvancedServerListAPI{
private static AdvancedServerListAPI instance;
private final Map<String, PlaceholderProvider> placeholderProviders = new HashMap<>();
private AdvancedServerListAPI(){}
/**
* Retrieves the instance used of this API.
* <br>If no instance has been made so far will a new one be created.
*
* @return Instance of this API.
*/
public static AdvancedServerListAPI get(){
if(instance != null)
return instance;
return (instance = new AdvancedServerListAPI());
}
/**
* Adds the provided {@link PlaceholderProvider PlaceholderProvider} to the list, if it passes the following checks:
* <ul>
* <li>The identifier is not null or empty.</li>
* <li>The identifier does not contain any spaces.</li>
* <li>A PlaceholderProvider with the same identifier doesn't exist already.</li>
* </ul>
* Not passing any of the above checks results in a
* {@link ch.andre601.advancedserverlist.api.exceptions.InvalidPlaceholderProviderException InvalidPlaceholderProviderException}
* being thrown.
*
* @param placeholderProvider
* The {@link PlaceholderProvider PlaceholderProvider} to add.
*
* @throws ch.andre601.advancedserverlist.api.exceptions.InvalidPlaceholderProviderException
* When the provided {@link PlaceholderProvider PlaceholderProvider instance} has a null or empty identifier,
* the identifier contains spaces or another provider with the same identifier is already loaded.
*/
public void addPlaceholderProvider(PlaceholderProvider placeholderProvider){
CheckUtil.notEmpty(placeholderProvider.getIdentifier(), "Identifier");
String identifier = placeholderProvider.getIdentifier().toLowerCase(Locale.ROOT);
CheckUtil.check(identifier.contains(" "), "Identifier may not contain spaces.");
CheckUtil.check(placeholderProviders.containsKey(identifier), "A PlaceholderProvider with name " + identifier + " already exists.");
placeholderProviders.put(identifier, placeholderProvider);
}
/**
* Retrieves the {@link PlaceholderProvider PlaceholderProvider} associated with the given identifier, or {@code null}
* should no such entry exist.
*
* @param identifier
* The identifier to find a matching {@link PlaceholderProvider PlaceholderProvider} for.
*
* @return Possibly-null {@link PlaceholderProvider PlaceholderProvider instance}.
*/
public PlaceholderProvider retrievePlaceholderProvider(String identifier){
return placeholderProviders.get(identifier.toLowerCase(Locale.ROOT));
}
}
@@ -1,97 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.api;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
/**
* Abstract class that is used to provide your own Placeholder patterns for AdvancedServerList to parse.
*
* <p>In order for your class to be considered a valid PlaceholderProvider will you need to set the
* {@link #identifier identifier} to a non-null, non-empty value without having any spaces in it.
* <br>Once set, use {@link ch.andre601.advancedserverlist.api.AdvancedServerListAPI#addPlaceholderProvider(PlaceholderProvider) AdvancedServerListAPI#addPlaceholderProvider(PlaceholderProvider)}
* to register your class for AdvancedServerList to use.
*/
public abstract class PlaceholderProvider{
private final String identifier;
/**
* Constructor used to set the identifier for the class extending the PlaceholderProvider class.
*
* <h2>Example</h2>
* <pre>{@code
* public class MyPlaceholders extends PlaceholderProvider {
*
* public MyPlaceholders() {
* super("myplaceholders");
* }
*
* @Override
* public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server) {
* if(placeholder.equals("hello")
* return "Hi!";
*
* return null;
* }
* }
* }</pre>
*
* @param identifier
* The identifier to use for the placeholder. Shouldn't be null nor empty.
*/
public PlaceholderProvider(String identifier){
this.identifier = identifier;
}
/**
* Method called by AdvancedServerList's StringReplacer class to replace any appearances of
* {@code ${<identifier> <placeholder>}} with whatever value a PlaceholderProvider may return.
*
* <p>Returning {@code null} will be treated as an invalid placeholder, returning the full placeholder as-is without
* any changes made.
*
* @param placeholder
* The part of the placeholder after the identifier ({@code ${<identifier> <placeholder>}}
* @param player
* The {@link GenericPlayer GenericPlayer instance} used.
* @param server
* The {@link GenericServer GenericServer instance} used.
*
* @return Parsed String based on the PlaceholderProvider or {@code null} for invalid placeholders.
*/
public abstract String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server);
/**
* Returns the identifier used by this instance.
*
* @return String containing the identifier used by this instance.
*/
public String getIdentifier(){
return identifier;
}
}
@@ -1,136 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.api.objects;
import java.util.UUID;
/**
* A basic abstract class used to store generic player data with to use in placeholder resolving.
* <br>The different variants of AdvancedServerList extend their own class with this one and may or may not use all values
* available here.
*
* <p>The following values will always be present, no matter the platform this class is used on:
* <ul>
* <li>{@link #getName() Name of Player}</li>
* <li>{@link #getProtocol() Protocol version of Player}</li>
* <li>{@link #getUUID() UUID of Player}</li>
* </ul>
* Any other value is not guaranteed to be accurate or even be set.
*/
public abstract class GenericPlayer{
protected String name = null;
protected int protocol = -1;
protected UUID uuid = null;
protected String version = null;
protected boolean playedBefore = false;
protected boolean banned = false;
protected boolean whitelisted = false;
/**
* Returns the name of the player.
* <br>Note that on Spigot, Paper and other forks can the name differ from the one cached by AdvancedServerList,
* if the plugin was able to retrieve an OfflinePlayer instance from the server. On BungeeCord and Velocity will
* the returned String always be the name from the cache.
*
* <p>Name may be whatever has been defined in AdvancedServerList's config.yml, should the player not be cached yet
* by AdvancedServerList.
*
* @return String representing the player's name.
*/
public String getName(){
return name;
}
/**
* Returns the protocol ID the player is using. The protocol ID is an integer used by Minecraft to determine what
* version a server or client is running.
*
* @return Integer representing the protocol version of this player.
*/
public int getProtocol(){
return protocol;
}
/**
* Returns the Unique ID associated with this player.
*
* <p>UUID may be whatever has been defined in AdvancedServerList's config.yml, should the player not be cached yet
* by AdvancedServerList.
*
* @return UUID of the player.
*/
public UUID getUUID(){
return uuid;
}
/**
* Returns the {@link #getProtocol() protocol version} in a readable MC version format (i.e. 1.19.3).
*
* <p>This only works on Velocity and will return {@code null} for any other platform.
*
* @return The readable MC version the player uses.
*/
public String getVersion(){
return version;
}
/**
* Returns whether this player has played on the Server before.
*
* <p>The returned boolean is <b>always</b> false on BungeeCord and Velocity due to a lack of any offline player data
* storage.
*
* @return Boolean indicating whether this player has played on this Server before.
*/
public boolean hasPlayedBefore() {
return playedBefore;
}
/**
* Returns whether this player is banned on the server.
*
* <p>The returned boolean is <b>always</b> false on BungeeCord and Velocity due to a lack of any offline player data
* storage.
*
* @return Boolean indicating whether this player was banned from the server.
*/
public boolean isBanned(){
return banned;
}
/**
* Returns whether this player is whitelisted on the server.
*
* <p>The returned boolean is <b>always</b> false on BungeeCord and Velocity due to a lack of any offline player data
* storage.
*
* @return Boolean indicating whether this player was banned from the server.
*/
public boolean isWhitelisted(){
return whitelisted;
}
}
@@ -1,70 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.api.objects;
/**
* Simple class used to wrap around some generic server data such as online player count, amount of total players that
* can join and the host (IP/Domain) that got pinged by the player.
*/
public class GenericServer{
private final int playersOnline;
private final int playersMax;
private final String host;
public GenericServer(int playersOnline, int playersMax, String host){
this.playersOnline = playersOnline;
this.playersMax = playersMax;
this.host = host;
}
/**
* Returns the number of players currently online on the server.
*
* @return Number of players online on the server.
*/
public int getPlayersOnline(){
return playersOnline;
}
/**
* Returns the number of total players that can join the server.
*
* @return Number of total players that can join the server.
*/
public int getPlayersMax(){
return playersMax;
}
/**
* Returns the IP/Domain that got pinged by the player.
*
* @return Possibly-null String containing the IP/Domain that got pinged by the player.
*/
public String getHost(){
return host;
}
}
+35 -12
View File
@@ -34,7 +34,7 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spigot</artifactId>
<artifactId>bukkit</artifactId>
<packaging>jar</packaging>
<version>${plugin.version}</version>
@@ -44,6 +44,10 @@
</properties>
<repositories>
<repository>
<id>papermc</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
<repository>
<id>spigot</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
@@ -56,6 +60,10 @@
<id>placeholderapi-repo</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
<repository>
<id>viaversion</id>
<url>https://repo.viaversion.com/</url>
</repository>
</repositories>
<dependencies>
@@ -65,6 +73,18 @@
<version>${plugin.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>platform-spigot</artifactId>
<version>${api.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.19.3-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
@@ -74,30 +94,37 @@
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-bukkit</artifactId>
<version>4.2.0</version>
<version>4.3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>4.8.0</version>
<version>5.0.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>3.0.0</version>
<version>3.0.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.11.2</version>
<version>2.11.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.viaversion</groupId>
<artifactId>viaversion-api</artifactId>
<version>4.6.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>AdvancedServerList-Spigot-${plugin.version}</finalName>
<finalName>AdvancedServerList-Bukkit-${plugin.version}</finalName>
<resources>
<resource>
<filtering>true</filtering>
@@ -108,7 +135,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<version>3.11.0</version>
<configuration>
<release>16</release>
</configuration>
@@ -116,7 +143,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.0</version>
<version>3.4.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
@@ -124,10 +151,6 @@
<pattern>org.bstats</pattern>
<shadedPattern>ch.andre601.advancedserverlist.spigot.depends.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>com.github.benmanes.caffeine</pattern>
<shadedPattern>ch.andre601.advancedserverlist.spigot.depends.caffeine</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
@@ -23,29 +23,53 @@
*
*/
package ch.andre601.advancedserverlist.spigot.commands;
package ch.andre601.advancedserverlist.bukkit.commands;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import ch.andre601.advancedserverlist.core.interfaces.commands.CmdSender;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.paper.commands.PaperCmdSender;
import ch.andre601.advancedserverlist.spigot.commands.SpigotCmdSender;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public class CmdAdvancedServerList implements CommandExecutor{
import java.util.Collections;
public class CmdAdvancedServerList extends Command implements CommandExecutor{
SpigotCore plugin;
BukkitAudiences bukkitAudiences;
private final PluginCore<?> plugin;
private final BukkitAudiences audiences;
public CmdAdvancedServerList(SpigotCore plugin){
public CmdAdvancedServerList(PluginCore<?> plugin){
this(plugin, null);
}
public CmdAdvancedServerList(PluginCore<?> plugin, BukkitAudiences audiences){
super(
"advancedserverlist",
"Main command of the plugin",
"/asl [reload|help]",
Collections.singletonList("asl")
);
this.plugin = plugin;
bukkitAudiences = BukkitAudiences.create(plugin);
this.audiences = audiences;
}
public boolean execute(@NotNull CommandSender sender, @NotNull String s, @NotNull String[] args){
plugin.getCore().getCommandHandler().handle(getSender(sender), args);
return true;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, @NotNull String[] args){
plugin.getCore().getCommandHandler().handle(new SpigotCmdSender(sender, bukkitAudiences), args);
plugin.getCore().getCommandHandler().handle(getSender(sender), args);
return true;
}
private CmdSender getSender(CommandSender sender){
return audiences == null ? new PaperCmdSender(sender) : new SpigotCmdSender(sender, audiences);
}
}
@@ -23,9 +23,9 @@
*
*/
package ch.andre601.advancedserverlist.spigot.events;
package ch.andre601.advancedserverlist.bukkit.events;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -35,9 +35,9 @@ import java.net.InetSocketAddress;
public class JoinEvent implements Listener{
private final SpigotCore plugin;
private final PluginCore<?> plugin;
public JoinEvent(SpigotCore plugin){
public JoinEvent(PluginCore<?> plugin){
this.plugin = plugin;
}
@@ -46,7 +46,7 @@ public class JoinEvent implements Listener{
InetSocketAddress address = event.getPlayer().getAddress();
if(address == null)
return;
Player player = event.getPlayer();
plugin.getCore().getPlayerHandler().addPlayer(address.getHostString(), player.getName(), player.getUniqueId());
}
@@ -23,15 +23,14 @@
*
*/
package ch.andre601.advancedserverlist.api.exceptions;
package ch.andre601.advancedserverlist.bukkit.events;
/**
* RuntimeException thrown whenever an invalid {@link ch.andre601.advancedserverlist.api.PlaceholderProvider PlaceholderProvider}
* has been given.
*/
public class InvalidPlaceholderProviderException extends RuntimeException{
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.spigot.events.PreServerListSetEvent;
public class PreServerListSetEventImpl extends PreServerListSetEvent{
public InvalidPlaceholderProviderException(String msg){
super(msg);
public PreServerListSetEventImpl(ProfileEntry entry){
super(entry);
}
}
@@ -23,18 +23,18 @@
*
*/
package ch.andre601.advancedserverlist.spigot.logging;
package ch.andre601.advancedserverlist.bukkit.logging;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SpigotLogger implements PluginLogger{
public class BukkitLogger implements PluginLogger{
private final Logger logger;
public SpigotLogger(Logger logger){
public BukkitLogger(Logger logger){
this.logger = logger;
}
@@ -23,29 +23,30 @@
*
*/
package ch.andre601.advancedserverlist.spigot.objects;
package ch.andre601.advancedserverlist.bukkit.objects;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.spigot.objects.SpigotPlayer;
public class PlayerPlaceholders extends PlaceholderProvider{
public class BukkitPlayerPlaceholders extends PlaceholderProvider{
public PlayerPlaceholders(){
public BukkitPlayerPlaceholders(){
super("player");
}
@Override
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
SpigotPlayer spigotPlayer = (SpigotPlayer)player;
SpigotPlayer bukkitPlayer = (SpigotPlayer)player;
return switch(placeholder){
case "name" -> spigotPlayer.getName();
case "protocol" -> String.valueOf(spigotPlayer.getProtocol());
case "uuid" -> String.valueOf(spigotPlayer.getUUID());
case "hasPlayedBefore" -> returnValue(spigotPlayer, player.hasPlayedBefore());
case "isBanned" -> returnValue(spigotPlayer, player.isBanned());
case "isWhitelisted" -> returnValue(spigotPlayer, player.isWhitelisted());
case "name" -> bukkitPlayer.getName();
case "protocol" -> String.valueOf(bukkitPlayer.getProtocol());
case "uuid" -> bukkitPlayer.getUUID().toString();
case "hasPlayedBefore" -> returnValue(bukkitPlayer, bukkitPlayer.hasPlayedBefore());
case "isBanned" -> returnValue(bukkitPlayer, bukkitPlayer.isBanned());
case "isWhitelisted" -> returnValue(bukkitPlayer, bukkitPlayer.isWhitelisted());
default -> null;
};
}
@@ -0,0 +1,145 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.bukkit.objects;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.objects.GenericServerImpl;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileManager;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import ch.andre601.advancedserverlist.spigot.events.ProtocolLibEvents;
import com.comphenix.protocol.ProtocolLibrary;
import com.viaversion.viaversion.api.Via;
import me.clip.placeholderapi.PlaceholderAPI;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.net.InetSocketAddress;
import java.util.Locale;
public class PAPIPlaceholders extends PlaceholderExpansion{
private final PluginCore<?> plugin;
public PAPIPlaceholders(PluginCore<?> plugin){
this.plugin = plugin;
this.register();
}
@Override
public @NotNull String getIdentifier(){
return "asl";
}
@Override
public @NotNull String getAuthor(){
return "Andre601";
}
@Override
public @NotNull String getVersion(){
return plugin.getCore().getVersion();
}
@Override
public String onPlaceholderRequest(Player pl, @NotNull String identifier){
InetSocketAddress address = pl.getAddress();
String host = resolveVirtualHost(pl, address);
CachedPlayer cached = plugin.getCore().getPlayerHandler().getCachedPlayer(pl.getUniqueId());
int protocol = resolveProtocol(pl);
int online = Bukkit.getOnlinePlayers().size();
int max = Bukkit.getMaxPlayers();
GenericServer server = new GenericServerImpl(online, max, host);
GenericPlayer player = new SpigotPlayerImpl(pl, cached, protocol);
ServerListProfile profile = ProfileManager.resolveProfile(plugin.getCore(), player, server);
if(profile == null)
return null;
ProfileEntry entry = ProfileManager.merge(profile);
if(ProfileManager.checkOption(entry.extraPlayersEnabled()))
max = online + (entry.extraPlayersCount() == null ? 0 : entry.extraPlayersCount());
GenericServer finalServer = new GenericServerImpl(online, max, host);
return switch(identifier.toLowerCase(Locale.ROOT)){
case "motd" -> ComponentParser.list(entry.motd())
.modifyText(text -> PlaceholderAPI.setPlaceholders(pl, text))
.modifyText(text -> StringReplacer.replace(text, player, finalServer))
.toString();
case "favicon" -> ComponentParser.text(entry.favicon())
.modifyText(text -> PlaceholderAPI.setPlaceholders(pl, text))
.modifyText(text -> StringReplacer.replace(text, player, finalServer))
.toString();
case "playercount_hover" -> ComponentParser.list(entry.players())
.modifyText(text -> PlaceholderAPI.setPlaceholders(pl, text))
.modifyText(text -> StringReplacer.replace(text, player, finalServer))
.toString();
case "playercount_text" -> ComponentParser.text(entry.playerCountText())
.modifyText(text -> PlaceholderAPI.setPlaceholders(pl, text))
.modifyText(text -> StringReplacer.replace(text, player, finalServer))
.toString();
case "extra_players_max" -> String.valueOf(max);
default -> null;
};
}
private int resolveProtocol(Player player){
if(Bukkit.getPluginManager().isPluginEnabled("ViaVersion"))
return Via.getAPI().getPlayerVersion(player.getUniqueId());
// Since Spigot version requires ProtocolLib can we use it here safely if the plugin instance is SpigotCore.
if(plugin instanceof SpigotCore)
return ProtocolLibrary.getProtocolManager().getProtocolVersion(player);
// getProtocolVersion is only in Paper, so this is only called when main class isn't SpigotCore
return Bukkit.getUnsafe().getProtocolVersion();
}
private String resolveVirtualHost(Player player, InetSocketAddress address){
try {
// Server is a Paper Server with Player#getVirtualHost()
Class.forName("com.destroystokyo.paper.network.NetworkClient");
return player.getVirtualHost() == null ? null : player.getVirtualHost().getHostString();
}catch(ClassNotFoundException ignored){}
if(address == null)
return null;
return ProtocolLibEvents.getHostAddresses().get(address.getHostString());
}
}
@@ -23,17 +23,21 @@
*
*/
package ch.andre601.advancedserverlist.spigot.objects;
package ch.andre601.advancedserverlist.bukkit.objects;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayerImpl;
import ch.andre601.advancedserverlist.spigot.objects.SpigotPlayer;
import org.bukkit.OfflinePlayer;
public class SpigotPlayer extends GenericPlayer{
public class SpigotPlayerImpl extends GenericPlayerImpl implements SpigotPlayer{
private final OfflinePlayer player;
private boolean playedBefore = false;
private boolean banned = false;
private boolean whitelisted = false;
public SpigotPlayer(OfflinePlayer player, CachedPlayer cachedPlayer, int protocol){
public SpigotPlayerImpl(OfflinePlayer player, CachedPlayer cachedPlayer, int protocol){
this.player = player;
this.name = player == null ? cachedPlayer.getName() : player.getName();
@@ -49,7 +53,23 @@ public class SpigotPlayer extends GenericPlayer{
this.whitelisted = player.isWhitelisted();
}
@Override
public OfflinePlayer getPlayer(){
return player;
}
@Override
public boolean hasPlayedBefore(){
return playedBefore;
}
@Override
public boolean isBanned(){
return banned;
}
@Override
public boolean isWhitelisted(){
return whitelisted;
}
}
@@ -0,0 +1,61 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.paper;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import io.papermc.paper.plugin.loader.PluginClasspathBuilder;
import io.papermc.paper.plugin.loader.PluginLoader;
import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.repository.RemoteRepository;
import org.jetbrains.annotations.NotNull;
public class ASLLoader implements PluginLoader{
@Override
public void classloader(@NotNull PluginClasspathBuilder pluginClasspathBuilder){
ComponentLogger logger = pluginClasspathBuilder.getContext().getLogger();
logger.info(Component.text("Loading Libraries for plugin..."));
MavenLibraryResolver resolver = new MavenLibraryResolver();
resolver.addRepository(new RemoteRepository.Builder(
"paper-maven",
"default",
"https://repo.papermc.io/repository/maven-public/"
).build());
logger.info(Component.text("Loading com.squareup.okhttp3:okhttp:4.10.0 from repo.papermc.io..."));
resolver.addDependency(new Dependency(new DefaultArtifact("com.squareup.okhttp3:okhttp:4.10.0"), null));
pluginClasspathBuilder.addLibrary(resolver);
logger.info(Component.text("Loading libraries complete!"));
}
}
@@ -0,0 +1,132 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.paper;
import ch.andre601.advancedserverlist.bukkit.commands.CmdAdvancedServerList;
import ch.andre601.advancedserverlist.bukkit.events.JoinEvent;
import ch.andre601.advancedserverlist.bukkit.logging.BukkitLogger;
import ch.andre601.advancedserverlist.bukkit.objects.BukkitPlayerPlaceholders;
import ch.andre601.advancedserverlist.bukkit.objects.PAPIPlaceholders;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import ch.andre601.advancedserverlist.paper.events.PaperPingEvent;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.CachedServerIcon;
import java.nio.file.Path;
public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon>{
private final PluginLogger logger = new BukkitLogger(getLogger());
private AdvancedServerList core;
private FaviconHandler<CachedServerIcon> faviconHandler;
@Override
public void onEnable(){
this.core = new AdvancedServerList(this, new BukkitPlayerPlaceholders());
if(getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
new PAPIPlaceholders(this);
}
@Override
public void onDisable(){
getCore().disable();
}
@Override
public void loadCommands(){
if(getServer().getCommandMap().register("asl", new CmdAdvancedServerList(this))){
getPluginLogger().info("Registered /advancedserverlist:advancedserverlist");
}else{
getPluginLogger().info("Registered /asl:advancedserverlist");
}
}
@Override
public void loadEvents(){
new JoinEvent(this);
new PaperPingEvent(this);
}
@Override
public void loadMetrics(){
new Metrics(this, 15584).addCustomChart(new SimplePie("profiles",
() -> String.valueOf(core.getFileHandler().getProfiles().size())
));
}
@Override
public void clearFaviconCache(){
if(faviconHandler == null)
return;
faviconHandler.clearCache();
}
@Override
public AdvancedServerList getCore(){
return core;
}
@Override
public Path getFolderPath(){
return getDataFolder().toPath();
}
@Override
public PluginLogger getPluginLogger(){
return logger;
}
@Override
public FaviconHandler<CachedServerIcon> getFaviconHandler(){
if(faviconHandler == null)
faviconHandler = new FaviconHandler<>(core);
return faviconHandler;
}
@Override
public String getPlatformName(){
return getServer().getName();
}
@Override
public String getPlatformVersion(){
return getServer().getVersion();
}
@Override
public String getLoader(){
return "paper";
}
}
@@ -25,7 +25,7 @@
package ch.andre601.advancedserverlist.paper.commands;
import ch.andre601.advancedserverlist.core.interfaces.CmdSender;
import ch.andre601.advancedserverlist.core.interfaces.commands.CmdSender;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import org.bukkit.command.CommandSender;
@@ -25,12 +25,17 @@
package ch.andre601.advancedserverlist.paper.events;
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.bukkit.events.PreServerListSetEventImpl;
import ch.andre601.advancedserverlist.bukkit.objects.SpigotPlayerImpl;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.paper.PaperCore;
import ch.andre601.advancedserverlist.paper.objects.PaperPlayer;
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
import com.destroystokyo.paper.profile.PlayerProfile;
import me.clip.placeholderapi.PlaceholderAPI;
@@ -40,9 +45,11 @@ import org.bukkit.OfflinePlayer;
import org.bukkit.util.CachedServerIcon;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon, PlayerProfile, PaperPlayer>{
public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon, SpigotPlayerImpl>{
private final PaperCore plugin;
private final PaperServerListPingEvent event;
@@ -52,6 +59,14 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
this.event = event;
}
@Override
public GenericServerListEvent callEvent(ProfileEntry entry){
PreServerListSetEventImpl event = new PreServerListSetEventImpl(entry);
plugin.getServer().getPluginManager().callEvent(event);
return event;
}
@Override
public void setMaxPlayers(int maxPlayers){
event.setMaxPlayers(maxPlayers);
@@ -74,12 +89,25 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
}
@Override
public void setPlayers(List<String> players, PaperPlayer player, GenericServer server){
public void setPlayers(List<String> lines, SpigotPlayerImpl player, GenericServer server){
event.getPlayerSample().clear();
List<PlayerProfile> players = new ArrayList<>(lines.size());
event.getPlayerSample().addAll(
plugin.createPlayers(players, player, server)
);
for(String line : lines){
String parsed = ComponentParser.text(line)
.modifyText(text -> StringReplacer.replace(text, player, server))
.modifyText(text -> {
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
return text;
})
.toString();
players.add(Bukkit.createProfile(UUID.randomUUID(), parsed));
}
event.getPlayerSample().addAll(players);
}
@Override
@@ -123,7 +151,7 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
}
@Override
public String parsePAPIPlaceholders(String text, PaperPlayer player){
public String parsePAPIPlaceholders(String text, SpigotPlayerImpl player){
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
@@ -136,15 +164,15 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
}
@Override
public PluginCore<CachedServerIcon, PlayerProfile, PaperPlayer> getPlugin(){
public PluginCore<CachedServerIcon> getPlugin(){
return plugin;
}
@Override
public PaperPlayer createPlayer(CachedPlayer player, int protocol){
public SpigotPlayerImpl createPlayer(CachedPlayer player, int protocol){
OfflinePlayer pl = Bukkit.getOfflinePlayer(player.getUuid());
return new PaperPlayer(pl.hasPlayedBefore() ? pl : null, player, protocol);
return new SpigotPlayerImpl(pl.hasPlayedBefore() ? pl : null, player, protocol);
}
@Override
@@ -31,17 +31,17 @@ import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class PingEvent implements Listener{
public class PaperPingEvent implements Listener{
private final PaperCore plugin;
public PingEvent(PaperCore plugin){
public PaperPingEvent(PaperCore plugin){
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onServerPing(PaperServerListPingEvent event){
public void onPaperServerListPing(PaperServerListPingEvent event){
PingEventHandler.handleEvent(new PaperEventWrapper(plugin, event));
}
}
@@ -25,33 +25,26 @@
package ch.andre601.advancedserverlist.spigot;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.bukkit.commands.CmdAdvancedServerList;
import ch.andre601.advancedserverlist.bukkit.logging.BukkitLogger;
import ch.andre601.advancedserverlist.bukkit.objects.BukkitPlayerPlaceholders;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import ch.andre601.advancedserverlist.spigot.commands.CmdAdvancedServerList;
import ch.andre601.advancedserverlist.spigot.events.LoadEvent;
import ch.andre601.advancedserverlist.spigot.logging.SpigotLogger;
import ch.andre601.advancedserverlist.spigot.objects.PlayerPlaceholders;
import ch.andre601.advancedserverlist.spigot.objects.SpigotPlayer;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedServerPing;
import me.clip.placeholderapi.PlaceholderAPI;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie;
import org.bukkit.command.PluginCommand;
import org.bukkit.plugin.java.JavaPlugin;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class SpigotCore extends JavaPlugin implements PluginCore<WrappedServerPing.CompressedImage, WrappedGameProfile, SpigotPlayer>{
public class SpigotCore extends JavaPlugin implements PluginCore<WrappedServerPing.CompressedImage>{
private final PluginLogger logger = new SpigotLogger(getLogger());
private final PluginLogger logger = new BukkitLogger(getLogger());
private AdvancedServerList core;
FaviconHandler<WrappedServerPing.CompressedImage> faviconHandler = null;
@@ -71,7 +64,7 @@ public class SpigotCore extends JavaPlugin implements PluginCore<WrappedServerPi
}catch(ClassNotFoundException ignored){}
}
this.core = new AdvancedServerList(this, new PlayerPlaceholders());
this.core = new AdvancedServerList(this, new BukkitPlayerPlaceholders());
}
@Override
@@ -83,10 +76,10 @@ public class SpigotCore extends JavaPlugin implements PluginCore<WrappedServerPi
public void loadCommands(){
PluginCommand cmd = getServer().getPluginCommand("advancedserverlist");
if(cmd == null){
getPluginLogger().warn("Could not register command /advancedserverlist");
getPluginLogger().warn("Unable to register command /advancedserverlist");
return;
}
cmd.setExecutor(new CmdAdvancedServerList(this));
cmd.setExecutor(new CmdAdvancedServerList(this, BukkitAudiences.create(this)));
}
@Override
@@ -147,27 +140,6 @@ public class SpigotCore extends JavaPlugin implements PluginCore<WrappedServerPi
return "spigot";
}
@Override
public List<WrappedGameProfile> createPlayers(List<String> lines, SpigotPlayer player, GenericServer server){
List<WrappedGameProfile> players = new ArrayList<>(lines.size());
for(String line : lines){
String parsed = ComponentParser.text(line)
.applyReplacements(player, server)
.modifyText(text -> {
if(getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
return text;
})
.toString();
players.add(new WrappedGameProfile(UUID.randomUUID(), parsed));
}
return players;
}
private void printPaperInfo(){
getPluginLogger().warn("======================================================================================");
getPluginLogger().warn("You are using the Spigot version of AdvancedServerList on a Paper server.");
@@ -25,7 +25,7 @@
package ch.andre601.advancedserverlist.spigot.commands;
import ch.andre601.advancedserverlist.core.interfaces.CmdSender;
import ch.andre601.advancedserverlist.core.interfaces.commands.CmdSender;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.command.CommandSender;
@@ -25,7 +25,9 @@
package ch.andre601.advancedserverlist.spigot.events;
import ch.andre601.advancedserverlist.bukkit.events.JoinEvent;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import ch.andre601.advancedserverlist.bukkit.objects.PAPIPlaceholders;
import com.comphenix.protocol.ProtocolLibrary;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@@ -53,6 +55,9 @@ public class LoadEvent implements Listener{
}
manager.registerEvents(new JoinEvent(plugin), plugin);
manager.registerEvents(new PingEvent(plugin, ProtocolLibrary.getProtocolManager()), plugin);
manager.registerEvents(new ProtocolLibEvents(plugin, ProtocolLibrary.getProtocolManager()), plugin);
if(manager.isPluginEnabled("PlaceholderAPI"))
new PAPIPlaceholders(plugin);
}
}
@@ -25,12 +25,17 @@
package ch.andre601.advancedserverlist.spigot.events;
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.bukkit.events.PreServerListSetEventImpl;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import ch.andre601.advancedserverlist.spigot.objects.SpigotPlayer;
import ch.andre601.advancedserverlist.bukkit.objects.SpigotPlayerImpl;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.AdventureComponentConverter;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
@@ -41,23 +46,28 @@ import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class ProtocolLibEventWrapper implements GenericEventWrapper<WrappedServerPing.CompressedImage, WrappedGameProfile, SpigotPlayer>{
public class ProtocolLibEventWrapper implements GenericEventWrapper<WrappedServerPing.CompressedImage, SpigotPlayerImpl>{
private final SpigotCore plugin;
private final PacketEvent event;
private final WrappedServerPing ping;
private final Map<String, String> hostAddresses;
public ProtocolLibEventWrapper(SpigotCore plugin, PacketEvent event, Map<String, String> hostAddresses){
public ProtocolLibEventWrapper(SpigotCore plugin, PacketEvent event){
this.plugin = plugin;
this.event = event;
this.ping = event.getPacket().getServerPings().read(0);
}
@Override
public GenericServerListEvent callEvent(ProfileEntry entry){
PreServerListSetEventImpl event = new PreServerListSetEventImpl(entry);
plugin.getServer().getPluginManager().callEvent(event);
this.hostAddresses = hostAddresses;
return event;
}
@Override
@@ -82,10 +92,24 @@ public class ProtocolLibEventWrapper implements GenericEventWrapper<WrappedServe
}
@Override
public void setPlayers(List<String> players, SpigotPlayer player, GenericServer server){
ping.setPlayers(
plugin.createPlayers(players, player, server)
);
public void setPlayers(List<String> lines, SpigotPlayerImpl player, GenericServer server){
List<WrappedGameProfile> players = new ArrayList<>(lines.size());
for(String line : lines){
String parsed = ComponentParser.text(line)
.modifyText(text -> StringReplacer.replace(text, player, server))
.modifyText(text -> {
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
return text;
})
.toString();
players.add(new WrappedGameProfile(UUID.randomUUID(), parsed));
}
ping.setPlayers(players);
}
@Override
@@ -100,7 +124,9 @@ public class ProtocolLibEventWrapper implements GenericEventWrapper<WrappedServe
// Not used in ProtocolLib
@Override
public void updateEvent(){}
public void updateEvent(){
event.getPacket().getServerPings().write(0, ping);
}
@Override
public boolean isInvalidProtocol(){
@@ -128,7 +154,7 @@ public class ProtocolLibEventWrapper implements GenericEventWrapper<WrappedServe
}
@Override
public String parsePAPIPlaceholders(String text, SpigotPlayer player){
public String parsePAPIPlaceholders(String text, SpigotPlayerImpl player){
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
@@ -141,19 +167,19 @@ public class ProtocolLibEventWrapper implements GenericEventWrapper<WrappedServe
if(host == null)
return null;
return hostAddresses.get(host);
return ProtocolLibEvents.getHostAddresses().get(host);
}
@Override
public PluginCore<WrappedServerPing.CompressedImage, WrappedGameProfile, SpigotPlayer> getPlugin(){
public PluginCore<WrappedServerPing.CompressedImage> getPlugin(){
return plugin;
}
@Override
public SpigotPlayer createPlayer(CachedPlayer player, int protocol){
public SpigotPlayerImpl createPlayer(CachedPlayer player, int protocol){
OfflinePlayer pl = Bukkit.getOfflinePlayer(player.getUuid());
return new SpigotPlayer(pl.hasPlayedBefore() ? pl : null, player, protocol);
return new SpigotPlayerImpl(pl.hasPlayedBefore() ? pl : null, player, protocol);
}
@Override
@@ -38,18 +38,22 @@ import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
public class PingEvent implements Listener{
public class ProtocolLibEvents implements Listener{
private final ProtocolManager protocolManager;
private final Map<String, String> hostAddresses = new HashMap<>();
private static final Map<String, String> hostAddresses = new HashMap<>();
public PingEvent(SpigotCore plugin, ProtocolManager protocolManager){
public ProtocolLibEvents(SpigotCore plugin, ProtocolManager protocolManager){
this.protocolManager = protocolManager;
loadPacketListener(plugin);
}
public static Map<String, String> getHostAddresses(){
return hostAddresses;
}
private void loadPacketListener(SpigotCore spigotPlugin){
protocolManager.addPacketListener(new PacketAdapter(spigotPlugin, ListenerPriority.LOW, PacketType.Handshake.Client.SET_PROTOCOL){
@Override
@@ -67,7 +71,7 @@ public class PingEvent implements Listener{
protocolManager.addPacketListener(new PacketAdapter(spigotPlugin, ListenerPriority.LOW, PacketType.Status.Server.SERVER_INFO){
@Override
public void onPacketSending(PacketEvent event){
PingEventHandler.handleEvent(new ProtocolLibEventWrapper(spigotPlugin, event, hostAddresses));
PingEventHandler.handleEvent(new ProtocolLibEventWrapper(spigotPlugin, event));
}
});
}
@@ -4,16 +4,26 @@ version: '${plugin.version}'
description: '${plugin.description}'
main: 'ch.andre601.advancedserverlist.paper.PaperCore'
loader: 'ch.andre601.advancedserverlist.paper.ASLLoader'
api-version: 1.19
libraries:
- 'com.squareup.okhttp3:okhttp:4.10.0'
dependencies:
- name: PlaceholderAPI
required: false
bootstrap: false
- name: ViaVersion
required: false
bootstrap: false
softdepend:
- 'PlaceholderAPI'
load-after:
- name: PlaceholderAPI
bootstrap: false
- name: ViaVersion
bootstrap: false
commands:
# The below stuff is NOT used by Paper plugin.
commands:
advancedserverlist:
description: 'Main command of AdvancedServerList'
usage: '/<command> [help|reload]'
@@ -21,11 +31,11 @@ commands:
- 'asl'
permission: 'advancedserverlist.admin'
permissions:
permissions:
advancedserverlist.*:
description: 'Grants access to all permissions'
default: op
children:
children:
- 'advancedserverlist.admin'
advancedserverlist.admin:
description: 'Grants access to all permissions'
@@ -7,6 +7,8 @@ main: 'ch.andre601.advancedserverlist.spigot.SpigotCore'
api-version: 1.19
folia-supported: true
libraries:
- 'org.spongepowered:configurate-yaml:4.1.2'
- 'net.kyori:adventure-api:4.12.0'
+31 -5
View File
@@ -58,6 +58,12 @@
<version>${plugin.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>platform-bungeecord</artifactId>
<version>${api.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
@@ -72,6 +78,18 @@
<type>javadoc</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.13.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.13.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-bungeecord</artifactId>
@@ -84,6 +102,18 @@
<version>3.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.spongepowered</groupId>
<artifactId>configurate-yaml</artifactId>
<version>4.1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
@@ -98,7 +128,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<version>3.11.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -119,10 +149,6 @@
<pattern>org.bstats</pattern>
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>com.github.benmanes.caffeine</pattern>
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.caffeine</shadedPattern>
</relocation>
<relocation>
<pattern>okhttp3</pattern>
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.okhttp3</shadedPattern>
@@ -25,30 +25,23 @@
package ch.andre601.advancedserverlist.bungeecord;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.bungeecord.commands.CmdAdvancedServerList;
import ch.andre601.advancedserverlist.bungeecord.events.JoinEvent;
import ch.andre601.advancedserverlist.bungeecord.events.PingEvent;
import ch.andre601.advancedserverlist.bungeecord.logging.BungeeLogger;
import ch.andre601.advancedserverlist.bungeecord.objects.BungeePlayer;
import ch.andre601.advancedserverlist.bungeecord.objects.PlayerPlaceholders;
import ch.andre601.advancedserverlist.bungeecord.objects.BungeePlayerPlaceholders;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import net.md_5.bungee.api.Favicon;
import net.md_5.bungee.api.ServerPing;
import net.md_5.bungee.api.plugin.Plugin;
import org.bstats.bungeecord.Metrics;
import org.bstats.charts.SimplePie;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class BungeeCordCore extends Plugin implements PluginCore<Favicon, ServerPing.PlayerInfo, BungeePlayer>{
public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
private AdvancedServerList core;
private FaviconHandler<Favicon> faviconHandler = null;
@@ -56,7 +49,7 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon, Server
@Override
public void onEnable(){
this.core = new AdvancedServerList(this, new PlayerPlaceholders());
this.core = new AdvancedServerList(this, new BungeePlayerPlaceholders());
}
@Override
@@ -128,19 +121,4 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon, Server
public String getLoader(){
return "bungeecord";
}
@Override
public List<ServerPing.PlayerInfo> createPlayers(List<String> lines, BungeePlayer player, GenericServer server){
List<ServerPing.PlayerInfo> players = new ArrayList<>(lines.size());
for(String line : lines){
String parsed = ComponentParser.text(line)
.applyReplacements(player, server)
.toString();
players.add(new ServerPing.PlayerInfo(parsed, UUID.randomUUID()));
}
return players;
}
}
@@ -25,7 +25,7 @@
package ch.andre601.advancedserverlist.bungeecord.commands;
import ch.andre601.advancedserverlist.core.interfaces.CmdSender;
import ch.andre601.advancedserverlist.core.interfaces.commands.CmdSender;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import net.kyori.adventure.platform.bungeecord.BungeeAudiences;
import net.md_5.bungee.api.CommandSender;
@@ -26,11 +26,15 @@
package ch.andre601.advancedserverlist.bungeecord.events;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
import ch.andre601.advancedserverlist.bungeecord.objects.BungeePlayer;
import ch.andre601.advancedserverlist.bungeecord.objects.BungeePlayerImpl;
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.api.Favicon;
@@ -41,8 +45,9 @@ import net.md_5.bungee.api.event.ProxyPingEvent;
import java.awt.image.BufferedImage;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.UUID;
public class BungeeEventWrapper implements GenericEventWrapper<Favicon, ServerPing.PlayerInfo, BungeePlayer>{
public class BungeeEventWrapper implements GenericEventWrapper<Favicon, BungeePlayerImpl>{
private final BungeeCordCore plugin;
private final ProxyPingEvent event;
@@ -56,6 +61,14 @@ public class BungeeEventWrapper implements GenericEventWrapper<Favicon, ServerPi
this.ping = event.getResponse();
}
@Override
public GenericServerListEvent callEvent(ProfileEntry entry){
PreServerListSetEventImpl event = new PreServerListSetEventImpl(entry);
plugin.getProxy().getPluginManager().callEvent(event);
return event;
}
@Override
public void setMaxPlayers(int maxPlayers){
ping.getPlayers().setMax(maxPlayers);
@@ -78,11 +91,20 @@ public class BungeeEventWrapper implements GenericEventWrapper<Favicon, ServerPi
}
@Override
public void setPlayers(List<String> players, BungeePlayer player, GenericServer server){
ServerPing.PlayerInfo[] playerInfos = plugin.createPlayers(players, player, server).toArray(new ServerPing.PlayerInfo[0]);
public void setPlayers(List<String> lines, BungeePlayerImpl player, GenericServer server){
ServerPing.PlayerInfo[] players = new ServerPing.PlayerInfo[lines.size()];
if(playerInfos.length > 0)
ping.getPlayers().setSample(playerInfos);
for(int i = 0; i < players.length; i++){
String parsed = ComponentParser.text(lines.get(i))
.modifyText(text -> StringReplacer.replace(text, player, server))
.toString();
ServerPing.PlayerInfo pi = new ServerPing.PlayerInfo(parsed, UUID.randomUUID());
players[i] = pi;
}
if(players.length > 0)
ping.getPlayers().setSample(players);
}
@Override
@@ -127,7 +149,7 @@ public class BungeeEventWrapper implements GenericEventWrapper<Favicon, ServerPi
}
@Override
public String parsePAPIPlaceholders(String text, BungeePlayer player){
public String parsePAPIPlaceholders(String text, BungeePlayerImpl player){
return text;
}
@@ -137,13 +159,13 @@ public class BungeeEventWrapper implements GenericEventWrapper<Favicon, ServerPi
}
@Override
public PluginCore<Favicon, ServerPing.PlayerInfo, BungeePlayer> getPlugin(){
public PluginCore<Favicon> getPlugin(){
return plugin;
}
@Override
public BungeePlayer createPlayer(CachedPlayer player, int protocol){
return new BungeePlayer(player, protocol);
public BungeePlayerImpl createPlayer(CachedPlayer player, int protocol){
return new BungeePlayerImpl(player, protocol);
}
@Override
@@ -0,0 +1,35 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.bungeecord.events;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
public class PreServerListSetEventImpl extends PreServerListSetEvent{
public PreServerListSetEventImpl(ProfileEntry entry){
super(entry);
}
}
@@ -25,12 +25,12 @@
package ch.andre601.advancedserverlist.bungeecord.objects;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayerImpl;
public class BungeePlayer extends GenericPlayer{
public class BungeePlayerImpl extends GenericPlayerImpl{
public BungeePlayer(CachedPlayer player, int protocol){
public BungeePlayerImpl(CachedPlayer player, int protocol){
this.name = player.getName();
this.protocol = protocol;
this.uuid = player.getUuid();
@@ -31,9 +31,9 @@ import ch.andre601.advancedserverlist.api.objects.GenericServer;
import java.util.Locale;
public class PlayerPlaceholders extends PlaceholderProvider{
public class BungeePlayerPlaceholders extends PlaceholderProvider{
public PlayerPlaceholders(){
public BungeePlayerPlaceholders(){
super("player");
}
+20 -12
View File
@@ -52,50 +52,58 @@
<dependencies>
<dependency>
<groupId>ch.andre601.advancedserverlist</groupId>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>api</artifactId>
<version>${plugin.version}</version>
<version>${api.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.spongepowered</groupId>
<artifactId>configurate-yaml</artifactId>
<version>4.1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.12.0</version>
<version>4.13.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.12.0</version>
<version>4.13.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-legacy</artifactId>
<version>4.12.0</version>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.2</version>
<scope>compile</scope>
<version>4.13.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.unascribed</groupId>
<artifactId>flexver-java</artifactId>
<version>1.1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
<scope>provided</scope>
</dependency>
<!-- Test dependencies -->
@@ -119,7 +127,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<version>3.11.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -27,11 +27,11 @@ package ch.andre601.advancedserverlist.core;
import ch.andre601.advancedserverlist.api.AdvancedServerListAPI;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.internal.ServerPlaceholders;
import ch.andre601.advancedserverlist.core.check.UpdateChecker;
import ch.andre601.advancedserverlist.core.commands.CommandHandler;
import ch.andre601.advancedserverlist.core.file.FileHandler;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.objects.ServerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.players.PlayerHandler;
import java.io.IOException;
@@ -41,7 +41,7 @@ import java.util.Properties;
public class AdvancedServerList{
private final PluginCore<?, ?, ?> plugin;
private final PluginCore<?> plugin;
private final FileHandler fileHandler;
private final CommandHandler commandHandler;
private final PlayerHandler playerHandler;
@@ -51,18 +51,19 @@ public class AdvancedServerList{
private String version;
public AdvancedServerList(PluginCore<?, ?, ?> plugin, PlaceholderProvider player){
public AdvancedServerList(PluginCore<?> plugin, PlaceholderProvider player){
this.plugin = plugin;
this.fileHandler = new FileHandler(this);
this.commandHandler = new CommandHandler(this);
this.playerHandler = new PlayerHandler(this);
this.api.addPlaceholderProvider(player);
this.api.addPlaceholderProvider(new ServerPlaceholders());
load();
}
public PluginCore<?, ?, ?> getPlugin(){
public PluginCore<?> getPlugin(){
return plugin;
}
@@ -102,6 +103,10 @@ public class AdvancedServerList{
plugin.clearFaviconCache();
}
public void clearPlayerCache(){
getPlayerHandler().clearCache();
}
private void load(){
printBanner();
resolveVersion();
@@ -149,7 +154,6 @@ public class AdvancedServerList{
}
private void printBanner(){
getPlugin().getPluginLogger().info("");
getPlugin().getPluginLogger().info(" _____ _");
getPlugin().getPluginLogger().info(" /\\ / ____| |");
getPlugin().getPluginLogger().info(" / \\ | (___ | |");
@@ -26,56 +26,121 @@
package ch.andre601.advancedserverlist.core.commands;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.CmdSender;
import ch.andre601.advancedserverlist.core.interfaces.commands.CmdSender;
import ch.andre601.advancedserverlist.core.interfaces.commands.PluginCommand;
import java.util.ArrayList;
import java.util.List;
public class CommandHandler{
private final AdvancedServerList core;
private final List<PluginCommand> subCommands = new ArrayList<>();
public CommandHandler(AdvancedServerList core){
this.core = core;
subCommands.add(new Help());
subCommands.add(new Reload(core));
subCommands.add(new ClearCache(core));
}
public void handle(CmdSender sender, String[] args){
String errorPrefix = "<grey>[<gradient:dark_red:red>AdvancedServerList</gradient>]";
String prefix = "<grey>[<gradient:aqua:white>AdvancedServerList</gradient>]";
if(args.length == 0){
sender.sendErrorMsg("<red>Too few arguments! Use <grey>/asl help</grey> for a list of commands.");
return;
}
if(args.length == 0 || args[0].equalsIgnoreCase("help")){
if(sender.hasPermission("advancedserverlist.command.help")){
sender.sendMsg("%s - Commands", prefix);
sender.sendMsg();
sender.sendMsg("<gradient:aqua:white>/asl help</gradient> <grey>- Shows this Help");
sender.sendMsg();
sender.sendMsg("<gradient:aqua:white>/asl reload</gradient> <grey>- Reloads the plugin");
}else{
sender.sendMsg("%s <red>You do not have permissions to execute this command!", errorPrefix);
}
}else
if(args[0].equalsIgnoreCase("reload")){
if(sender.hasPermission("advancedserverlist.command.reload")){
sender.sendMsg("%s Reloading plugin...", prefix);
if(core.getFileHandler().reloadConfig()){
sender.sendMsg("%s <green>Reloaded <grey>config.yml</grey>!", prefix);
}else{
sender.sendMsg("%s <red>Error while reloading the <grey>config.yml</grey>!", errorPrefix);
for(PluginCommand subCommand : subCommands){
if(subCommand.getArgument().equalsIgnoreCase(args[0])){
if(!sender.hasPermission(subCommand.getPermission())){
sender.sendErrorMsg(
"<red>You do not have the permission <grey>%s</grey> to execute this command.",
subCommand.getPermission()
);
return;
}
if(core.getFileHandler().reloadProfiles()){
sender.sendMsg("%s <green>Loaded <grey>%d Profile(s)</grey>!", prefix, core.getFileHandler().getProfiles().size());
}else{
sender.sendMsg("%s <red>Cannot load Profiles!", errorPrefix);
}
core.clearFaviconCache();
sender.sendMsg("%s <green>Successfully cleared Favicon cache!", prefix);
sender.sendMsg("%s <green>Reload complete!", prefix);
}else{
sender.sendMsg("%s <red>You do not have permissions to execute this command!", errorPrefix);
subCommand.handle(sender);
return;
}
}else{
sender.sendMsg("%s <red>Unknown subcommand <grey>%s</grey>. Use <grey>/asl help</grey> for a list of commands.", prefix, args[0]);
}
sender.sendErrorMsg("<red>Unknown subcommand <grey>%s</grey>. Use <grey>/asl help</grey> for a list of commands.", args[0]);
}
private static class Help extends PluginCommand{
public Help(){
super("help");
}
@Override
public void handle(CmdSender sender){
sender.sendPrefixedMsg("- Commands");
sender.sendMsg();
sender.sendMsg("<aqua>/asl <white>help <grey>- Shows this help");
sender.sendMsg();
sender.sendMsg("<aqua>/asl <white>reload <grey>- Reloads the plugin and clears caches");
sender.sendMsg();
sender.sendMsg("<aqua>/asl <white>clearCache <grey>- Clears the Player and Favicon cache");
}
}
private static class Reload extends PluginCommand{
private final AdvancedServerList core;
public Reload(AdvancedServerList core){
super("reload");
this.core = core;
}
@Override
public void handle(CmdSender sender){
sender.sendPrefixedMsg("Reloading plugin...");
if(core.getFileHandler().reloadConfig()){
sender.sendPrefixedMsg("<green>Reloaded <grey>config.yml</grey>!");
}else{
sender.sendErrorMsg("<red>Error while reloading <grey>config.yml</grey>!");
}
if(core.getFileHandler().reloadProfiles()){
sender.sendPrefixedMsg("<green>Loaded <grey>%d profile(s)</grey>!", core.getFileHandler().getProfiles().size());
}else{
sender.sendErrorMsg("<red>Error while loading profile(s)!");
}
core.clearFaviconCache();
sender.sendPrefixedMsg("<green>Successfully cleared Favicon Cache!");
core.clearPlayerCache();
sender.sendPrefixedMsg("<green>Successfully cleared Player Cache!");
sender.sendPrefixedMsg("<green>Reload complete!");
}
}
private static class ClearCache extends PluginCommand{
private final AdvancedServerList core;
public ClearCache(AdvancedServerList core){
super("clearCache");
this.core = core;
}
@Override
public void handle(CmdSender sender){
sender.sendPrefixedMsg("Clearing caches...");
core.clearFaviconCache();
sender.sendPrefixedMsg("<green>Successfully cleared Favicon Cache!");
core.clearPlayerCache();
sender.sendPrefixedMsg("<green>Successfully cleared Player Cache!");
sender.sendPrefixedMsg("<green>Cache clearing complete!");
}
}
}
@@ -25,23 +25,25 @@
package ch.andre601.advancedserverlist.core.events;
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
import ch.andre601.advancedserverlist.core.objects.GenericServerImpl;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileEntry;
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileManager;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
public class PingEventHandler{
public static <F, PL, P extends GenericPlayer> void handleEvent(GenericEventWrapper<F, PL, P> event){
public static <F, P extends GenericPlayer> void handleEvent(GenericEventWrapper<F, P> event){
if(event.isInvalidProtocol())
return;
PluginCore<F, PL, P> plugin = event.getPlugin();
PluginCore<F> plugin = event.getPlugin();
String host = event.getVirtualHost();
int online = event.getOnlinePlayers();
@@ -51,54 +53,58 @@ public class PingEventHandler{
plugin.getCore().getPlayerHandler().getCachedPlayer(event.getPlayerIP()),
event.getProtocolVersion()
);
GenericServer server = new GenericServer(online, max, host);
ServerListProfile profile = ProfileManager.get(plugin.getCore())
.applyReplacements(player, server)
.getProfile();
GenericServer server = new GenericServerImpl(online, max, host);
ServerListProfile profile = ProfileManager.resolveProfile(plugin.getCore(), player, server);
if(profile == null)
return;
ProfileEntry entry = ProfileManager.merge(profile);
if(entry.isExtraPlayersEnabled().getValue(false)){
max = online + (entry.getExtraPlayersCount() == null ? 0 : entry.getExtraPlayersCount());
GenericServerListEvent e = event.callEvent(ProfileManager.merge(profile));
if(e == null || e.isCancelled())
return;
ProfileEntry entry = e.getEntry();
if(entry.isInvalid())
return;
if(ProfileManager.checkOption(entry.extraPlayersEnabled())){
max = online + (entry.extraPlayersCount() == null ? 0 : entry.extraPlayersCount());
event.setMaxPlayers(max);
}
server = new GenericServer(online, max, host);
GenericServer finalServer = new GenericServerImpl(online, max, host);
if(!entry.getMOTD().isEmpty()){
if(ProfileManager.checkOption(entry.motd())){
event.setMotd(
ComponentParser.list(entry.getMOTD())
.applyReplacements(player, server)
ComponentParser.list(entry.motd())
.modifyText(text -> StringReplacer.replace(text, player, finalServer))
.modifyText(text -> event.parsePAPIPlaceholders(text, player))
.toComponent()
);
}
boolean hidePlayers = entry.isHidePlayersEnabled().getValue(false);
boolean hidePlayers = ProfileManager.checkOption(entry.hidePlayersEnabled());
if(hidePlayers){
event.hidePlayers();
}
if(!entry.getPlayerCountText().isEmpty() && !hidePlayers){
if(ProfileManager.checkOption(entry.playerCountText()) && !hidePlayers){
event.setPlayerCount(
ComponentParser.text(entry.getPlayerCountText())
.applyReplacements(player, server)
ComponentParser.text(entry.playerCountText())
.modifyText(text -> StringReplacer.replace(text, player, finalServer))
.modifyText(text -> event.parsePAPIPlaceholders(text, player))
.toString()
);
}
if(!entry.getPlayers().isEmpty() && !hidePlayers){
event.setPlayers(entry.getPlayers(), player, server);
if(ProfileManager.checkOption(entry.players()) && !hidePlayers){
event.setPlayers(entry.players(), player, server);
}
if(!entry.getFavicon().isEmpty()){
String favicon = StringReplacer.replace(entry.getFavicon(), player, server);
if(ProfileManager.checkOption(entry.favicon())){
String favicon = StringReplacer.replace(entry.favicon(), player, server);
F fav = plugin.getFaviconHandler().getFavicon(favicon, image -> {
try{
@@ -28,7 +28,7 @@ package ch.andre601.advancedserverlist.core.file;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileEntry;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileSerializer;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
@@ -0,0 +1,48 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.core.interfaces.commands;
public interface CmdSender{
String prefix = "<grey>[<gradient:aqua:white>AdvancedServerList</gradient>] ";
String errorPrefix = "<grey>[<gradient:dark_red:red>AdvancedServerList</gradient>] ";
boolean hasPermission(String permission);
void sendMsg(String msg, Object... args);
default void sendMsg(){
sendMsg("");
}
default void sendPrefixedMsg(String msg, Object... args){
sendMsg(prefix + msg, args);
}
default void sendErrorMsg(String msg, Object... args){
sendMsg(errorPrefix + msg, args);
}
}
@@ -23,18 +23,23 @@
*
*/
package ch.andre601.advancedserverlist.api.internal;
package ch.andre601.advancedserverlist.core.interfaces.commands;
import ch.andre601.advancedserverlist.api.exceptions.InvalidPlaceholderProviderException;
public class CheckUtil{
public abstract class PluginCommand{
public static void notEmpty(String text, String name){
check(text == null || text.isEmpty(), name + " may not be null or empty.");
private final String argument;
public PluginCommand(String argument){
this.argument = argument;
}
public static void check(boolean condition, String msg){
if(condition)
throw new InvalidPlaceholderProviderException(msg);
public String getArgument(){
return argument;
}
public String getPermission(){
return "advancedserverlist.command." + getArgument();
}
public abstract void handle(CmdSender sender);
}
@@ -25,16 +25,13 @@
package ch.andre601.advancedserverlist.core.interfaces.core;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import java.nio.file.Path;
import java.util.List;
public interface PluginCore<F, PL, P extends GenericPlayer>{
public interface PluginCore<F>{
void loadCommands();
@@ -57,6 +54,4 @@ public interface PluginCore<F, PL, P extends GenericPlayer>{
String getPlatformVersion();
String getLoader();
List<PL> createPlayers(List<String> lines, P player, GenericServer server);
}
@@ -27,6 +27,8 @@ package ch.andre601.advancedserverlist.core.interfaces.events;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import net.kyori.adventure.text.Component;
@@ -35,7 +37,9 @@ import java.awt.image.BufferedImage;
import java.net.InetSocketAddress;
import java.util.List;
public interface GenericEventWrapper<F, PL, P extends GenericPlayer>{
public interface GenericEventWrapper<F, P extends GenericPlayer>{
GenericServerListEvent callEvent(ProfileEntry entry);
void setMaxPlayers(int maxPlayers);
@@ -67,7 +71,7 @@ public interface GenericEventWrapper<F, PL, P extends GenericPlayer>{
String getVirtualHost();
PluginCore<F, PL, P> getPlugin();
PluginCore<F> getPlugin();
P createPlayer(CachedPlayer player, int protocol);
@@ -25,29 +25,32 @@
package ch.andre601.advancedserverlist.core.objects;
/*
* A simple class to allow having a nullable boolean without having to deal with possible NPEs
* when trying to get Boolean.getValue() while it is null...
*
* Here, it simply checks if the value is null and if it is, returns a default. Otherwise, it gives
* the value.
*/
public class NullBool{
import ch.andre601.advancedserverlist.api.objects.GenericServer;
public class GenericServerImpl implements GenericServer{
public static final NullBool FALSE = new NullBool(false);
public static final NullBool NULL = new NullBool(null);
private final int online;
private final int max;
private final String host;
private final Boolean value;
public NullBool(Boolean value){
this.value = value;
public GenericServerImpl(int online, int max, String host){
this.online = online;
this.max = max;
this.host = host;
}
public boolean isNull(){
return value == null;
@Override
public int getPlayersOnline(){
return online;
}
public boolean getValue(boolean def){
return isNull() ? def : value;
@Override
public int getPlayersMax(){
return max;
}
@Override
public String getHost(){
return host;
}
}
@@ -23,7 +23,7 @@
*
*/
package ch.andre601.advancedserverlist.api.internal;
package ch.andre601.advancedserverlist.core.objects;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
@@ -36,11 +36,11 @@ public class ServerPlaceholders extends PlaceholderProvider{
}
@Override
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
public String parsePlaceholder(String placeholder, GenericPlayer genericPlayer, GenericServer genericServer){
return switch(placeholder){
case "playersOnline" -> String.valueOf(server.getPlayersOnline());
case "playersMax" -> String.valueOf(server.getPlayersMax());
case "host" -> server.getHost();
case "playersOnline" -> String.valueOf(genericServer.getPlayersOnline());
case "playersMax" -> String.valueOf(genericServer.getPlayersMax());
case "host" -> genericServer.getHost();
default -> null;
};
}
@@ -25,9 +25,6 @@
package ch.andre601.advancedserverlist.core.parsing;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
@@ -59,11 +56,6 @@ public class ComponentParser{
return new ComponentParser(String.join("\n", lines));
}
public ComponentParser applyReplacements(GenericPlayer player, GenericServer server){
text = StringReplacer.replace(text, player, server);
return this;
}
public ComponentParser modifyText(Function<String, String> function){
this.text = function.apply(text);
return this;
@@ -27,9 +27,9 @@ package ch.andre601.advancedserverlist.core.profiles;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.conditions.Expression;
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileEntry;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
@@ -47,11 +47,12 @@ public class ServerListProfile{
private final Random random = new Random();
public ServerListProfile(int priority, List<Expression> expressions, List<ProfileEntry> profiles, ProfileEntry defaultProfile){
public ServerListProfile(int priority, List<Expression> expressions, ProfileEntry defaultProfile, List<ProfileEntry> profiles){
this.priority = priority;
this.expressions = expressions;
this.profiles = profiles;
this.defaultProfile = defaultProfile;
this.profiles = profiles;
}
public int getPriority(){
@@ -96,19 +97,19 @@ public class ServerListProfile{
*/
public boolean isInvalidProfile(){
if(profiles.isEmpty())
return defaultProfile.isInvalidProfile();
return defaultProfile.isInvalid();
boolean profilesValid = false;
for(ProfileEntry profile : profiles){
if(profile.isInvalidProfile())
if(profile.isInvalid())
continue;
profilesValid = true;
break;
}
return !profilesValid && defaultProfile.isInvalidProfile();
return !profilesValid && defaultProfile.isInvalid();
}
public static class Builder{
@@ -150,7 +151,7 @@ public class ServerListProfile{
return this;
for(String str : temp){
Expression expr = new Expression(str);
Expression expr = Expression.resolve(str);
if(expr.getResult() != Expression.ExpressionResult.VALID){
logger.warn("Found invalid expression in condition '%s'! Reason: %s", str, expr.getResult().getMessage());
@@ -183,7 +184,7 @@ public class ServerListProfile{
}
public ServerListProfile build(){
return new ServerListProfile(this.priority, this.expressions, this.profiles, this.defaultProfile);
return new ServerListProfile(this.priority, this.expressions, this.defaultProfile, this.profiles);
}
}
}
@@ -31,37 +31,34 @@ import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
public class Expression{
private ExpressionResult result = ExpressionResult.VALID;
private final ExpressionResult result;
private String left;
private Operator operator = Operator.UNKNOWN;
private String right;
private final String left;
private final Operator operator;
private final String right;
public Expression(String expression){
resolveExpression(expression);
private Expression(ExpressionResult result, String left, Operator operator, String right){
this.result = result;
this.left = left;
this.operator = operator;
this.right = right;
}
public boolean evaluate(GenericPlayer player, GenericServer server){
String newLeft = StringReplacer.replace(left, player, server);
String newRight = StringReplacer.replace(right, player, server);
public static Expression createInvalid(ExpressionResult result){
return new Expression(result, null, Operator.UNKNOWN, null);
}
public static Expression resolve(String expression){
Operator operator = Operator.UNKNOWN;
return operator.evaluate(newLeft, newRight);
}
public ExpressionResult getResult(){
return result;
}
private void resolveExpression(String expression){
if(expression == null || expression.isEmpty()){
result = ExpressionResult.INVALID_NO_EXPRESSION;
return;
return Expression.createInvalid(ExpressionResult.INVALID_NO_EXPRESSION);
}
char[] chars = expression.toCharArray();
StringBuilder left = new StringBuilder();
StringBuilder right = new StringBuilder();
StringBuilder leftBuilder = new StringBuilder();
StringBuilder rightBuilder = new StringBuilder();
boolean foundOperator = false;
@@ -81,19 +78,28 @@ public class Expression{
}
if(foundOperator){
right.append(c);
rightBuilder.append(c);
}else{
left.append(c);
leftBuilder.append(c);
}
}
if(left.isEmpty() || right.isEmpty()){
result = ExpressionResult.INVALID_EMPTY_PARTS;
return;
if(leftBuilder.isEmpty() || rightBuilder.isEmpty()){
return Expression.createInvalid(ExpressionResult.INVALID_EMPTY_PARTS);
}
this.left = left.toString();
this.right = right.toString();
return new Expression(ExpressionResult.VALID, leftBuilder.toString().trim(), operator, rightBuilder.toString().trim());
}
public boolean evaluate(GenericPlayer player, GenericServer server){
String newLeft = StringReplacer.replace(left, player, server);
String newRight = StringReplacer.replace(right, player, server);
return operator.evaluate(newLeft, newRight);
}
public ExpressionResult getResult(){
return result;
}
public enum Operator{
@@ -26,8 +26,8 @@
package ch.andre601.advancedserverlist.core.profiles.favicon;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import javax.imageio.ImageIO;
import java.awt.*;
@@ -39,12 +39,13 @@ import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Locale;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
public class FaviconHandler<F>{
private final Cache<String, F> favicons = Caffeine.newBuilder()
private final Cache<String, F> favicons = CacheBuilder.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.build();
@@ -55,13 +56,17 @@ public class FaviconHandler<F>{
}
public F getFavicon(String input, Function<BufferedImage, F> function){
return favicons.get(input, k -> {
BufferedImage image = resolveImage(core, input);
if(image == null)
return null;
return function.apply(image);
});
try{
return favicons.get(input, () -> {
BufferedImage image = resolveImage(core, input);
if(image == null)
return null;
return function.apply(image);
});
}catch(ExecutionException ignored){
return null;
}
}
public void clearCache(){
@@ -0,0 +1,52 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.core.profiles.players;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import java.util.UUID;
public abstract class GenericPlayerImpl implements GenericPlayer{
protected String name = null;
protected int protocol = 0;
protected UUID uuid = null;
@Override
public String getName(){
return name;
}
@Override
public int getProtocol(){
return protocol;
}
@Override
public UUID getUUID(){
return uuid;
}
}
@@ -128,6 +128,20 @@ public class PlayerHandler{
return getDefaultPlayer();
}
public CachedPlayer getCachedPlayer(UUID uuid){
for(CachedPlayer player : cachedPlayers){
if(player.getUuid().equals(uuid))
return player;
}
return getDefaultPlayer();
}
public void clearCache(){
cachedPlayers.clear();
defaultPlayer = null;
}
private boolean contains(String ip){
for(CachedPlayer player : cachedPlayers){
if(player.getIp().equals(ip))
@@ -1,194 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.core.profiles.profile;
import ch.andre601.advancedserverlist.core.objects.NullBool;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ProfileEntry{
private final List<String> motd;
private final List<String> players;
private final String playerCountText;
private final String favicon;
private final NullBool hidePlayersEnabled;
private final NullBool extraPlayersEnabled;
private final Integer extraPlayersCount;
public ProfileEntry(List<String> motd, List<String> players,
String playerCountText, String favicon, NullBool hidePlayersEnabled,
NullBool extraPlayersEnabled, Integer extraPlayersCount){
this.motd = motd;
this.players = players;
this.playerCountText = playerCountText;
this.favicon = favicon;
this.hidePlayersEnabled = hidePlayersEnabled;
this.extraPlayersEnabled = extraPlayersEnabled;
this.extraPlayersCount = extraPlayersCount;
}
public static ProfileEntry empty(){
return new ProfileEntry(Collections.emptyList(), Collections.emptyList(), "", "",
NullBool.FALSE, NullBool.FALSE, 0);
}
public List<String> getMOTD(){
return motd;
}
public List<String> getPlayers(){
return players;
}
public String getPlayerCountText(){
return playerCountText;
}
public String getFavicon(){
return favicon;
}
public NullBool isHidePlayersEnabled(){
return hidePlayersEnabled;
}
public NullBool isExtraPlayersEnabled(){
return extraPlayersEnabled;
}
public Integer getExtraPlayersCount(){
return extraPlayersCount;
}
public boolean isInvalidProfile(){
return getMOTD().isEmpty() &&
getPlayers().isEmpty() &&
(getPlayerCountText().isEmpty() && !isHidePlayersEnabled().getValue(false)) &&
getFavicon().isEmpty();
}
public static class Builder{
private final ConfigurationNode node;
private List<String> motd = new ArrayList<>();
private List<String> players = new ArrayList<>();
private String playerCountText = null;
private String favicon = null;
private NullBool hidePlayersEnabled = NullBool.FALSE;
private NullBool extraPlayersEnabled = NullBool.FALSE;
private Integer extraPlayersCount = 0;
private Builder(ConfigurationNode node){
this.node = node;
}
public static Builder resolve(ConfigurationNode node){
return new Builder(node)
.resolveMOTD()
.resolvePlayers()
.resolvePlayerCountText()
.resolveFavicon()
.resolveHidePlayersEnabled()
.resolveExtraPlayersEnabled()
.resolveExtraPlayersCount();
}
public Builder resolveMOTD(){
List<String> motd = resolveList(node, "motd");
if(motd.size() <= 2){
this.motd = motd;
return this;
}
this.motd = motd.subList(0, 2);
return this;
}
public Builder resolvePlayers(){
this.players = this.resolveList(node, "playerCount", "hover");
return this;
}
public Builder resolvePlayerCountText(){
this.playerCountText = node.node("playerCount", "text").getString("");
return this;
}
public Builder resolveFavicon(){
this.favicon = node.node("favicon").getString("");
return this;
}
public Builder resolveHidePlayersEnabled(){
if(node.node("playerCount", "hidePlayers").virtual()){
this.hidePlayersEnabled = NullBool.NULL;
return this;
}
this.hidePlayersEnabled = new NullBool(node.node("playerCount", "hidePlayers").getBoolean());
return this;
}
public Builder resolveExtraPlayersEnabled(){
if(node.node("playerCount", "extraPlayers", "enabled").virtual()){
this.extraPlayersEnabled = NullBool.NULL;
return this;
}
this.extraPlayersEnabled = new NullBool(node.node("playerCount", "extraPlayers", "enabled").getBoolean());
return this;
}
public Builder resolveExtraPlayersCount(){
if(node.node("playerCount", "extraPlayers", "amount").virtual()){
this.extraPlayersCount = null;
return this;
}
this.extraPlayersCount = node.node("playerCount", "extraPlayers", "amount").getInt();
return this;
}
public ProfileEntry build(){
return new ProfileEntry(this.motd, this.players, this.playerCountText,
this.favicon, this.hidePlayersEnabled, this.extraPlayersEnabled, this.extraPlayersCount);
}
private List<String> resolveList(ConfigurationNode node, Object... path){
try{
return node.node(path).getList(String.class);
}catch(SerializationException ex){
return Collections.emptyList();
}
}
}
}
@@ -27,46 +27,18 @@ package ch.andre601.advancedserverlist.core.profiles.profile;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.objects.NullBool;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.objects.NullBool;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.Collections;
import java.util.List;
public class ProfileManager{
private final AdvancedServerList core;
private GenericPlayer player;
private GenericServer server;
private ProfileManager(AdvancedServerList core){
this.core = core;
}
public static ProfileManager get(AdvancedServerList core){
return new ProfileManager(core);
}
public ProfileManager applyReplacements(GenericPlayer player, GenericServer server){
this.player = player;
this.server = server;
return this;
}
public ServerListProfile getProfile(){
for(ServerListProfile profile : core.getFileHandler().getProfiles()){
if(profile.isInvalidProfile())
continue;
if(profile.evalConditions(player, server))
return profile;
}
return null;
}
/*
* Convenience method to get a ProfileEntry instance with values merged.
* If the random profile's value is not null will it be used instead of the default one.
@@ -84,56 +56,126 @@ public class ProfileManager{
Integer extraPlayersCount = resolveExtraPlayersCount(entry, defEntry);
return new ProfileEntry(motd, players, playerCountText, favicon,
new NullBool(isHidePlayersEnabled), new NullBool(isExtraPlayersEnabled), extraPlayersCount);
NullBool.resolve(isHidePlayersEnabled), NullBool.resolve(isExtraPlayersEnabled), extraPlayersCount);
}
public static ServerListProfile resolveProfile(AdvancedServerList core, GenericPlayer player, GenericServer server){
for(ServerListProfile profile : core.getFileHandler().getProfiles()){
if(profile.isInvalidProfile())
continue;
if(profile.evalConditions(player, server))
return profile;
}
return null;
}
public static ProfileEntry retrieveProfileEntry(ConfigurationNode node){
List<String> motd = resolveList(node, "motd");
List<String> players = resolveList(node, "playerCount", "hover");
String playerCountText = node.node("playerCount", "text").getString("");
String favicon = node.node("favicon").getString("");
NullBool hidePlayers = resolveNullBool(node, "playerCount", "hidePlayers");
NullBool extraPlayersEnabled = resolveNullBool(node, "playerCount", "extraPlayers", "enabled");
Integer extraPlayers = resolveNullableInt(node);
return new ProfileEntry.Builder()
.setMotd(motd)
.setPlayers(players)
.setPlayerCountText(playerCountText)
.setFavicon(favicon)
.setHidePlayersEnabled(hidePlayers)
.setExtraPlayersEnabled(extraPlayersEnabled)
.setExtraPlayerCount(extraPlayers)
.build();
}
public static boolean checkOption(Object obj){
if(obj == null)
return false;
if(obj instanceof List<?> list){
return !list.isEmpty(); // Check if list isn't empty
}else
if(obj instanceof String str){
return !str.isEmpty(); // Check if String is not empty
}else
if(obj instanceof NullBool nb){
return nb.getOrDefault(false); // Return NullBool's value
}
return false;
}
private static List<String> resolveMOTD(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.getMOTD().isEmpty())
return defaultProfile.getMOTD();
if(profile == null || !checkOption(profile.motd()))
return defaultProfile.motd();
return profile.getMOTD();
return profile.motd();
}
private static List<String> resolvePlayers(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.getPlayers().isEmpty())
return defaultProfile.getPlayers();
if(profile == null || !checkOption(profile.players()))
return defaultProfile.players();
return profile.getPlayers();
return profile.players();
}
private static String resolvePlayerCountText(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.getPlayerCountText().isEmpty())
return defaultProfile.getPlayerCountText();
if(profile == null || !checkOption(profile.playerCountText()))
return defaultProfile.playerCountText();
return profile.getPlayerCountText();
return profile.playerCountText();
}
private static String resolveFavicon(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.getFavicon().isEmpty())
return defaultProfile.getFavicon();
if(profile == null || !checkOption(profile.favicon()))
return defaultProfile.favicon();
return profile.getFavicon();
return profile.favicon();
}
private static boolean resolveHidePlayersEnabled(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.isHidePlayersEnabled().isNull())
return defaultProfile.isHidePlayersEnabled().getValue(false);
if(profile == null || !checkOption(profile.hidePlayersEnabled()))
return defaultProfile.hidePlayersEnabled().getOrDefault(false);
return profile.isHidePlayersEnabled().getValue(false);
return profile.hidePlayersEnabled().getOrDefault(false);
}
private static boolean resolveExtraPlayersEnabled(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.isExtraPlayersEnabled().isNull())
return defaultProfile.isExtraPlayersEnabled().getValue(false);
if(profile == null || !checkOption(profile.extraPlayersEnabled()))
return defaultProfile.extraPlayersEnabled().getOrDefault(false);
return profile.isExtraPlayersEnabled().getValue(false);
return profile.extraPlayersEnabled().getOrDefault(false);
}
private static Integer resolveExtraPlayersCount(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.getExtraPlayersCount() == null)
return defaultProfile.getExtraPlayersCount() == null ? 0 : defaultProfile.getExtraPlayersCount();
if(profile == null || profile.extraPlayersCount() == null)
return defaultProfile.extraPlayersCount() == null ? 0 : defaultProfile.extraPlayersCount();
return profile.getExtraPlayersCount();
return profile.extraPlayersCount();
}
private static List<String> resolveList(ConfigurationNode node, Object... path){
try{
return node.node(path).getList(String.class);
}catch(SerializationException ex){
return Collections.emptyList();
}
}
private static NullBool resolveNullBool(ConfigurationNode node, Object... path){
if(node.node(path).virtual())
return NullBool.NOT_SET;
return NullBool.resolve(node.node(path).getBoolean());
}
private static Integer resolveNullableInt(ConfigurationNode node){
if(node.node("playerCount", "extraPlayers", "amount").virtual())
return null;
return node.node("playerCount", "extraPlayers", "amount").getInt();
}
}
@@ -29,6 +29,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.serialize.TypeSerializer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import java.lang.reflect.Type;
@@ -37,7 +38,7 @@ public class ProfileSerializer implements TypeSerializer<ProfileEntry>{
@Override
public ProfileEntry deserialize(Type type, ConfigurationNode node){
return ProfileEntry.Builder.resolve(node).build();
return ProfileManager.retrieveProfileEntry(node);
}
@Override
@@ -47,12 +48,12 @@ public class ProfileSerializer implements TypeSerializer<ProfileEntry>{
return;
}
node.node("motd").set(profile.getMOTD());
node.node("playerCount", "hover").set(profile.getPlayers());
node.node("playerCount", "text").set(profile.getPlayerCountText());
node.node("favicon").set(profile.getFavicon());
node.node("playerCount", "hidePlayers").set(profile.isHidePlayersEnabled());
node.node("playerCount", "extraPlayers", "enabled").set(profile.isExtraPlayersEnabled());
node.node("playerCount", "extraPlayers", "amount").set(profile.getExtraPlayersCount());
node.node("motd").set(profile.motd());
node.node("playerCount", "hover").set(profile.players());
node.node("playerCount", "text").set(profile.playerCountText());
node.node("favicon").set(profile.favicon());
node.node("playerCount", "hidePlayers").set(profile.hidePlayersEnabled());
node.node("playerCount", "extraPlayers", "enabled").set(profile.extraPlayersEnabled());
node.node("playerCount", "extraPlayers", "amount").set(profile.extraPlayersCount());
}
}
@@ -33,6 +33,9 @@ import ch.andre601.advancedserverlist.api.objects.GenericServer;
public class StringReplacer{
public static String replace(String input, GenericPlayer player, GenericServer server){
if(input == null)
return null;
char[] chars = input.toCharArray();
StringBuilder builder = new StringBuilder(input.length());
+60
View File
@@ -0,0 +1,60 @@
# Changelog
This page lists the recent changes made towards the AdvancedServerListAPI.
They are ordered newest to oldest.
## v2.1.0
### :octicons-pencil-24:{ .changelog-changed title="Changed" } Changed { #v-changed }
- Turned `ProfileEntry` class into a record
- Former `getX()` methods are now deprecated in favour of the recor's own `x()` methods (i.e. `getMotd()` -> `motd()`)
## v2.0.0
### :octicons-alert-24:{ .changelog-breaking title="Breaking Changes" } Breaking Changes { #v2-breaking }
- `platform-paper` has been removed. It used the same code as `platform-spigot` and was therefore considered duplicate code and useless.
- `core` has been removed. The `CachedPlayer` is no longer needed in the platform-specific APIs.
### :octicons-plus-circle-24:{ .changelog-added title="Added" } Added { #v2-added }
- `PreServerListSetEvent` to the different platform-specific APIs.
- Called before AdvancedServerList alters the server list.
- Allows to override the `ProfileEntry` used or even cancel the event.
- `ProfileEntry`
- Used for setting the different values of the server list.
- Own instances can be made using the nested `Builder` class.
- Has methods to create a Builder instance from itself, or make a copy from another ProfileEntry-instance.
### :octicons-pencil-24:{ .changelog-changed title="Changed" } Changed { #v2-changed }
- Converted `GenericPlayer`, `GenericServer`, `BungeePlayer`, `SpigotPlayer` and `VelocityPlayer` into interfaces.
- `GenericPlayer` no longer has `getVersion()`, `hasPlayedBefore()`, `isBanned()` and `isWhitelisted()`. They have been moved to `VelocityPlayer` (Only `getVersion()`) and `SpigotPlayer` respectively.
- Converted `NullBool` from a class to an enum.
- Contains `TRUE`, `FALSE` and `NOT_SET`.
- `isNull()` is now `isNotSet()`.
### :octicons-trash-24:{ .changelog-removed title="Removed" } Removed { #v2-removed }
- `UnsupportedAPIAccessException` as it is no longer used in the API itself.
## v1.0.0
### :octicons-plus-circle-24:{ .changelog-added title="Added" } Added { #v1-added }
- `AdvancedServerListAPI`
- Main class used to add your own `PlaceholderProvider` instances.
- `PlaceholderProvider`
- Abstract class used to add your own placeholders to parse in AdvancedServerList.
<!--
Templates for changelog
### :octicons-alert-24:{ .changelog-breaking title="Breaking Changes" } Breaking Changes { #v-breaking }
### :octicons-plus-circle-24:{ .changelog-added title="Added" } Added { #v-added }
### :octicons-pencil-24:{ .changelog-changed title="Changed" } Changed { #v-changed }
### :octicons-trash-24:{ .changelog-removed title="Removed" } Removed { #v-removed }
-->
+18 -9
View File
@@ -1,7 +1,7 @@
# API
AdvancedServerList v2 introduced a new API that plugins can hook into to use.
As of right now is it only providing a way to add your own placeholders for it to use.
It provides a way for your plugin to provide its own placeholders that should be parsed by AdvancedServerList and also an event to modify the server list.
## Add dependency
@@ -13,7 +13,7 @@ Add the following to your `build.gradle` or `pom.xml` file to use the API:
```groovy
repositorories {
maven { url = 'https://jitpack.io/" }
maven { url = 'https://jitpack.io/' }
}
dependencies {
@@ -21,7 +21,6 @@ Add the following to your `build.gradle` or `pom.xml` file to use the API:
// Optional platform dependencies
implementation 'ch.andre601.asl-api:platform-bungeecord:{version}'
implementation 'ch.andre601.asl-api:platform-paper:{version}'
implementation 'ch.andre601.asl-api:platform-spigot:{version}'
implementation 'ch.andre601.asl-api:platform-velocity:{version}'
}
@@ -52,11 +51,6 @@ Add the following to your `build.gradle` or `pom.xml` file to use the API:
<artifactId>platform-bungeecord</artifactId>
<version>{version}</version>
</dependency>
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>platform-paper</artifactId>
<version>{version}</version>
</dependency>
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>platform-spigot</artifactId>
@@ -139,4 +133,19 @@ Example:
AdvancedServerListAPI api = AdvancedServerListAPI.get();
api.addPlaceholderProvider(new MyPlaceholders());
```
```
## Events
!!! info "Note"
The mentioned event is only accessible through one of the platform dependencies, as those are used in the platform's respective event handler system.
v2 of the API adds the `PreServerListSetEvent` to the different platform dependencies to use.
It allows you to modify the ProfileEntry used for the player pinging the server/proxy or even cancelling the event altogether.
### ProfileEntry
The ProfileEntry class has been moved to the API in v2 allowing you to create your own versions using the available Builder class.
This class contains values from a Server List Profile file. The values can either be from a `profiles` list entry, one of the global options in the file, or a mix of both, depending on what options are present.
You can create a new entry or copy an existing one (i.e. from the [`PreServerListSetEvent`](#events)) to modify and use in the server list by setting it in the aforementioned `PreServerListSetEvent`.
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

+25
View File
@@ -5,4 +5,29 @@
.md-header__button.md-logo {
padding-right: unset;
padding-left: unset;
}
.changelog-added {
color: #2ea043;
}
.changelog-removed {
color: #f85149;
}
.changelog-changed {
color: #1f6feb;
}
.changelog-breaking {
color: #9e6a03
}
.md-banner--warning__icon {
color: #d29922;
}
/* Override mkdocs-material styling */
.md-banner--warning {
background: rgba(187,128,9,0.15);
}
+28
View File
@@ -0,0 +1,28 @@
# Commands
The plugin adds commands to use for various things related to the plugin itself.
The main command is `/advancedserverlist` but an alias called `/asl` is also registered to use.
## Permissions
The main permission is `advancedserverlist.admin` for all commands, but you can also grant access to specific commands using `advancedserverlist.command.<subcommand>` instead (i.e. `advancedserverlist.command.help` to grant access to [`/asl help`](#help)).
## Subcommands
The following subcommands are available (Subcommands are case-insensitive):
- [`help`](#help)
- [`reload`](#reload)
- [`clearCache`](#clearcache)
### help
Shows a list of all available [subcommands](#subcommands) for AdvancedServerList.
### reload
Reloads the plugin's `config.yml`, all available YAML files in the `profiles` folder and also clears the currently cached favicons and Players.
### clearCache
Clears the currently cached favicons and Players.
+23 -16
View File
@@ -9,21 +9,19 @@ If you're new to the plugin is it recommended to check out the [Profiles page](.
AdvancedServerList supports the following platforms:
<a href="https://www.spigotmc.org" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/spigot_vector.svg" width="64" alt="platform-spigot" title="Tested on Spigot">
</a>
<a href="https://papermc.io" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/paper_vector.svg" width="64" alt="platform-paper" title="Tested on Paper">
</a>
<a href="https://www.spigotmc.org" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/bungeecord_vector.svg" width="64" alt="platform-bungeecord" title="Tested on BungeeCord">
</a>
<a href="https://www.papermc.io" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/waterfall_vector.svg" width="64" alt="platform-waterfall" title="Tested on Waterfall">
</a>
<a href="https://velocitypowered.com" target="_blank">
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/velocity_vector.svg" width="64" alt="platform-velocity" title="Tested on Velocity">
</a>
[![spigot-img](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/spigot_vector.svg "Tested on Spigot"){ width=64 }][spigot]
[![paper-img](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/paper_vector.svg "Tested on Paper"){ width=64 }][paper]
[![bungeecord-img](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/bungeecord_vector.svg "Tested on BungeeCord"){ width=64 }][spigot]
[![waterfall](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/waterfall_vector.svg "Tested on Waterfall"){ width=64 }][paper]
[![velocity](https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/velocity_vector.svg "Tested on Velocity"){ width=64 }][velocity]
## Dependencies
| Dependency | Platforms | Required? |
|------------------|---------------|-----------|
| [ProtocolLib] | Spigot | Yes |
| [PlaceholderAPI] | Spigot, Paper | No |
| [ViaVersion] | Spigot, Paper | No |
## Pages
@@ -31,4 +29,13 @@ AdvancedServerList supports the following platforms:
- [Formatting](./profiles/formatting)
- [Placeholders](./profiles/placeholders)
- [API](./api)
- [Examples](./examples)
- [Examples](./examples)
- [PlaceholderAPI placeholders](./placeholderapi.md)
[spigot]: https://www.spigotmc.org
[paper]: https://papermc.io
[velocity]: https://velocitypowered.com
[protocollib]: https://www.spigotmc.org/resources/1997/
[placeholderapi]: https://www.spigotmc.org/resources/6245/
[viaversion]: https://www.spigotmc.org/resources/19254/
+18
View File
@@ -0,0 +1,18 @@
# PlaceholderAPI Placeholders
The Spigot and Paper version of AdvancedServerList provide their own set of placeholders to use through [PlaceholderAPI].
## Placeholders
!!! note
AdvancedServerList will try to find a matching Profile for the player similar to when they ping the server when using any of the below placeholders.
| Placeholder | Description |
|---------------------------|-------------------------------------------------------------------------------|
| `%asl_favicon%` | Gives the value of `favicon` from a matching Profile. |
| `%asl_extra_players_max%` | Gives the value of `playerCount.extraPlayers.amount` from a matching Profile. |
| `%asl_motd%` | Gives the value of `motd` in the matching Profile. |
| `%asl_playercount_hover%` | Gives the value of `playerCount.hover` from a matching Profile. |
| `%asl_playercount_text%` | Gives the value of `playerCount.text` from a matching Profile. |
[placeholderapi]: https://www.spigotmc.org/resources/6245/
+10 -28
View File
@@ -50,49 +50,31 @@ The following operants are available and can be used in the conditions.
## Profiles
!!! info "Available since v1.10.0"
The profiles option allows you to add multiple combinations of all the other options (With the exception of [`Priority`](#priority) and [`Conditions`](#conditions)) to have randomized MOTDs, player counts, etc.
If an option is not present in an entry will AdvancedServerList try to use one defined in the file or use whatever default value would be for that option.
As an example:
```yaml
priority: 1
priority: 0
profiles:
- motd:
- Line 1
- Line 2
- '<rainbow>Line 1</rainbow>'
- '<rainbow:!>Line 2</rainbow>'
playerCount:
text: 'Awesome!'
text: '<green><bold>Awesome!'
- playerCount:
text: 'Also Awesome'
text: '<yellow><bold>Also Awesome!'
motd:
- Line A
- Line B
- '<rainbow:2>Line A</rainbow>'
- '<rainbow:!2>Line B</rainbow>'
```
...the above file would randomly select between a MOTD saying `Line 1\nLine 2` and a player count saying `Awesome!` or a MOTD saying `Line A\nLine B` while the player count says `Also Awesome`
...the above example would randomly select between the following combinations of MOTD and Player count text:
## Motds
!!! warning "Only available in v1.9.0"
This option allows to create multiple MOTDs that AdvancedServerList should randomly select from.
Due to the structure of this option will you need to use `|-` to have multi-line MOTDs.
Example:
```yaml
motds:
- |-
Line 1
Line 2
- |-
Line A
Line B
```
![motd-example-1](../assets/images/examples/motd-example-1.jpg)
![motd-example-2](../assets/images/examples/motd-example-2.jpg)
## Motd
+2 -2
View File
@@ -12,7 +12,7 @@ The following placeholders are available in AdvancedServerList itself. Please no
These placeholders use the player who pinged the server, to return values. They may require the player to be cached in order to work.
| Placeholder | Description | Platforms | Cached Player required?\* |
| --------------------------- | --------------------------------------------------------------- | ------------ | ------------------------ |
|-----------------------------|-----------------------------------------------------------------|--------------|---------------------------|
| `${player name}` | The name of the player. | All | Yes\*\* |
| `${player protocol}` | The protocol version of the player. | All | No |
| `${player uuid}` | The UUID of the player. | All | Yes\*\*\* |
@@ -30,7 +30,7 @@ These placeholders use the player who pinged the server, to return values. They
These placeholders use values given by the server/proxy AdvancedServerList runs on.
| Placeholder | Description |
| ------------------------- | -------------------------------------------------------- |
|---------------------------|----------------------------------------------------------|
| `${server playersOnline}` | The number of players online on this server. |
| `${server playersMax}` | The total number of players that can join this server.\* |
| `${server host}` | The domain/IP the player pinged. |
+31 -64
View File
@@ -27,106 +27,73 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>parent</artifactId>
<groupId>ch.andre601.advancedserverlist</groupId>
<artifactId>parent</artifactId>
<version>parent</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>paper</artifactId>
<packaging>jar</packaging>
<version>${plugin.version}</version>
<artifactId>hangar-uploader</artifactId>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>papermc</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
<repository>
<id>placeholderapi-repo</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>ch.andre601.advancedserverlist</groupId>
<artifactId>core</artifactId>
<version>${plugin.version}</version>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.19-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>3.0.0</version>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.11.2</version>
<scope>provided</scope>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>AdvancedServerList-Paper-${plugin.version}</finalName>
<resources>
<resource>
<filtering>true</filtering>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<finalName>HangarUploader</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<version>3.11.0</version>
<configuration>
<release>16</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>ch.andre601.advancedserverlist.hangaruploader.HangarUploader</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>org.spongepowered.configurate</pattern>
<shadedPattern>ch.andre601.advancedserverlist.paper.depends.configurate</shadedPattern>
</relocation>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>ch.andre601.advancedserverlist.paper.depends.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>com.github.benmanes.caffeine</pattern>
<shadedPattern>ch.andre601.advancedserverlist.paper.depends.caffeine</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
@@ -0,0 +1,209 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.hangaruploader;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.mime.FileBody;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.entity.mime.StringBody;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpMessage;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
public class HangarUploader{
private static final Logger LOGGER = LoggerFactory.getLogger(HangarUploader.class);
private static final String API_URL = "https://hangar.papermc.io/api/v1/";
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private final String apiKey;
private ActiveJWT activeJWT;
public HangarUploader(String apiKey){
this.apiKey = apiKey;
}
public static void main(String[] args) throws IOException{
LOGGER.info("Starting Jar file...");
final VersionUpload.Namespace project = new VersionUpload.Namespace("Andre_601", "AdvancedServerList");
if(args.length < 3){
throw new IllegalStateException("Application requires HANGAR_TOKEN, RELEASE_TAG, PRERELEASE and RELEASE_BODY to work");
}
String apiToken = args[0];
String version = args[1].startsWith("v") ? args[1].substring(1) : args[1];
boolean isPreRelease = args[2].equalsIgnoreCase("true");
String body = System.getenv("GITHUB_RELEASE_BODY");
LOGGER.info("Version: {}", version);
LOGGER.info("Is Prerelease: {}", isPreRelease);
LOGGER.info("Release Message: {}", body);
final List<Path> filePaths = List.of(
new File("bukkit/target/AdvancedServerList-Bukkit-" + version + ".jar").toPath(),
new File("bungeecord/target/AdvancedServerList-BungeeCord-" + version + ".jar").toPath(),
new File("velocity/target/AdvancedServerList-Velocity-" + version + ".jar").toPath()
);
final List<VersionUpload.PluginDependency> paperDependencies = List.of(
VersionUpload.PluginDependency.createWithHangarNamespace(
"ViaVersion",
false,
new VersionUpload.Namespace("ViaVersion", "ViaVersion")
),
VersionUpload.PluginDependency.createWithExternalUrl(
"PlaceholderAPI",
false,
"https://www.spigotmc.org/resources/6245/"
)
);
final List<VersionUpload.MultipartFileOrUrl> fileInfo = List.of(
new VersionUpload.MultipartFileOrUrl(List.of(VersionUpload.Platform.PAPER), null),
new VersionUpload.MultipartFileOrUrl(List.of(VersionUpload.Platform.WATERFALL), null),
new VersionUpload.MultipartFileOrUrl(List.of(VersionUpload.Platform.VELOCITY), null)
);
final VersionUpload versionUpload = new VersionUpload(
version,
Map.of(
VersionUpload.Platform.PAPER, paperDependencies,
VersionUpload.Platform.WATERFALL, List.of(),
VersionUpload.Platform.VELOCITY, List.of()
),
Map.of(
VersionUpload.Platform.PAPER, List.of("1.19.x"),
VersionUpload.Platform.WATERFALL, List.of("1.19.x"),
VersionUpload.Platform.VELOCITY, List.of("3.1")
),
body,
fileInfo,
isPreRelease ? "Beta" : "Release"
);
HangarUploader uploader = new HangarUploader(apiToken);
try(CloseableHttpClient client = HttpClients.createDefault()){
uploader.uploadVersion(client, project, versionUpload, filePaths);
}catch(ParseException ex){
LOGGER.error("Encountered ParseException while performing a request.", ex);
}
}
public void uploadVersion(HttpClient client, VersionUpload.Namespace namespace, VersionUpload versionUpload,
List<Path> filePaths) throws IOException, ParseException{
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addPart("versionUpload", new StringBody(GSON.toJson(versionUpload), ContentType.APPLICATION_JSON));
for(Path path : filePaths){
builder.addPart("files", new FileBody(path.toFile(), ContentType.DEFAULT_BINARY));
}
HttpPost post = new HttpPost(API_URL + "projects/" + namespace + "/upload");
post.setEntity(builder.build());
this.addAuthHeader(client, post);
LOGGER.info("Uploading release...");
final boolean success = client.execute(post, response -> {
if(response.getCode() != 200){
LOGGER.error("Error while uploading version. Received response code {}: {}", response.getCode(), response.getReasonPhrase());
LOGGER.error("Body: {}", EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8));
return false;
}
return true;
});
if(!success){
throw new RuntimeException("Error uploading version!");
}
LOGGER.info("Upload complete!");
System.exit(0);
}
private synchronized void addAuthHeader(HttpClient client, HttpMessage message) throws IOException{
LOGGER.info("Applying Authorization Header...");
if(this.activeJWT != null && !this.activeJWT.hasExpired()){
message.addHeader("Authorization", this.activeJWT.jwt());
LOGGER.info("Authorization Header applied. Expires at {}", getDate(this.activeJWT.expiresAt()));
return;
}
LOGGER.info("Current JWT expired. Requesting new one...");
ActiveJWT jwt = client.execute(new HttpPost(API_URL + "authenticate?apiKey=" + this.apiKey), response -> {
if(response.getCode() == 400){
LOGGER.error("Bad JWT request; is the API-token valid?");
return null;
}else
if(response.getCode() != 200){
LOGGER.error("Received non-successful response code {}: {}", response.getCode(), response.getReasonPhrase());
return null;
}
final String json = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
final JsonObject jsonObject = GSON.fromJson(json, JsonObject.class);
final String token = jsonObject.getAsJsonPrimitive("token").getAsString();
final long expiresIn = jsonObject.getAsJsonPrimitive("expiresIn").getAsLong();
LOGGER.info("Received new JWT!");
return new ActiveJWT(token, System.currentTimeMillis() + expiresIn);
});
if(jwt == null){
throw new RuntimeException("Error getting JWT.");
}
this.activeJWT = jwt;
LOGGER.info("Authorization Header applied. Expires at {}", getDate(this.activeJWT.expiresAt()));
message.addHeader("Authorization", jwt.jwt());
}
private synchronized String getDate(long timestamp){
return timestamp + " (" + new Date(timestamp) + ")";
}
private record ActiveJWT(String jwt, long expiresAt){
public boolean hasExpired(){
return System.currentTimeMillis() < this.expiresAt + TimeUnit.SECONDS.toMillis(3);
}
}
}
@@ -0,0 +1,66 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.hangaruploader;
import java.util.List;
import java.util.Map;
public record VersionUpload(String version, Map<Platform, List<PluginDependency>> pluginDependencies,
Map<Platform, List<String>> platformDependencies, String description,
List<MultipartFileOrUrl> files, String channel){
public record Namespace(String owner, String slug){
@Override
public String toString(){
return this.owner + "/" + this.slug;
}
}
public record PluginDependency(String name, boolean required, Namespace namespace, String externalUrl){
public PluginDependency{
if(namespace == null && externalUrl == null)
throw new IllegalStateException("Either a Hangar Namespace or an external URL needs to be defined.");
}
public static PluginDependency createWithHangarNamespace(String name, boolean required, Namespace namespace){
return new PluginDependency(name, required, namespace, null);
}
public static PluginDependency createWithExternalUrl(String name, boolean required, String externalUrl){
return new PluginDependency(name, required, null, externalUrl);
}
}
public record MultipartFileOrUrl(List<Platform> platforms, String externalUrl){}
public enum Platform{
PAPER,
WATERFALL,
VELOCITY
}
}
@@ -0,0 +1,60 @@
<!--
~ MIT License
~
~ Copyright (c) 2022-2023 Andre_601
~
~ 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.
~
-->
<configuration debug="false">
<property name="DEV_HOME" value="./logs"/>
<!--CONSOLE -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%highlight([) %boldWhite(%d{dd.MM.yyyy HH:mm:ss}) %highlight(%-5level) %highlight(]) %cyan([%t]) %boldWhite([%logger{0}]) %boldRed(-) %white(%msg) %n</pattern>
</encoder>
</appender>
<!--FILE OUT-->
<appender name="FILE-AUDIT" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<file>${DEV_HOME}/Purr.log</file>
<encoder>
<pattern>%d{dd.MM.yyyy HH:mm:ss} [%thread] [ %-5level] [%logger{0}] %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${DEV_HOME}/archived/purr-%d{dd.MM.yyyy}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>60</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
</appender>
<!--Root logger-->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE-AUDIT"/>
</root>
</configuration>
+14 -426
View File
@@ -1,359 +1,43 @@
# +--------------------------------------------------------------------------------------------------------+
# | |
# | This is the main file used by MkDocs to build the pages. |
# | It contains a lot of information and settings for you to read and use. |
# | Comments may contain "Read More" URLs to more in-depth documentation about the option for you to read. |
# | |
# | You can check out https://www.mkdocs.org/user-guide/configuration/ for a more detailed explanation of |
# | all the options MkDocs offers by default. |
# | |
# +------------------------------------------------- NOTE -------------------------------------------------+
# | |
# | Some of the options listed here are only available through the usage of Material for MkDocs. |
# | Those options will usually have a link to the docs of this Theme and also mention "Material" as name. |
# | The actual name of the theme is "Material for MkDocs" and "Material" is used for simplicity reasons. |
# | |
# +--------------------------------------------------------------------------------------------------------+
# +--------------------------------------------------------------------------------------------------------+
# | |
# | Main Page Settings for MkDocs. |
# | Those settings are site name, site description, Site author and also Site URL (Canonical URL) |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#site_name |
# | - https://www.mkdocs.org/user-guide/configuration/#site_description |
# | - https://www.mkdocs.org/user-guide/configuration/#site_author |
# | - https://www.mkdocs.org/user-guide/configuration/#site_url |
# | |
# +--------------------------------------------------------------------------------------------------------+
site_name: AdvancedServerList Wiki
site_description: 'Wiki for the AdvancedServerList plugin'
site_author: 'Andre_601'
site_url: 'https://www.andre601.ch/AdvancedServerList' # Uncomment to set a canonical URL
# +--------------------------------------------------------------------------------------------------------+
# | |
# | This setting allows you to define your own Copyright notice. |
# | The text is treated as HTML code so you can use things like <a> tags or &copy; to display the |
# | Copyright icon. |
# | |
# | Where or IF the Copyright is displayed depends on the theme you use. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#copyright |
# | |
# +--------------------------------------------------------------------------------------------------------+
copyright: |
&copy; Andre_601
# +--------------------------------------------------------------------------------------------------------+
# | |
# | The base folder to use. |
# | Any Markdown files you put into this folder will be turned into a static HTML page once you build or |
# | publish your page. |
# | |
# | It is also used as the base directory for other settings like the "extra_css" or "extra_javascript" |
# | option. |
# | |
# +--------------------------------------------------------------------------------------------------------+
docs_dir: docs/
# +--------------------------------------------------------------------------------------------------------+
# | |
# | These options allow to define a Repository to link to. |
# | The result will, depending on the theme, be a link somewhere shown on the page that links to the |
# | Repository with the specified repo_name. |
# | |
# | This will also enable a "edit" button on the page itself that allows the direct editing of the page. |
# | You can disable this by setting "edit_uri" to an empty String. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#repo_name |
# | - https://www.mkdocs.org/user-guide/configuration/#repo_url |
# | - https://www.mkdocs.org/user-guide/configuration/#edit_uri |
# | |
# +--------------------------------------------------------------------------------------------------------+
repo_name: Andre601/AdvancedServerList
repo_url: https://github.com/Andre601/AdvancedServerList
#edit_uri: tree/master/docs # Uncomment to define a different URI/URL for the "edit" option
# +--------------------------------------------------------------------------------------------------------+
# | |
# | The "nav" option is where you define the navigation to show in MkDocs. |
# | |
# | Depending on the theme you use will the resulting Navigation look different. |
# | |
# | You can set different types of navigations. Either just the path, the path with a separate title or |
# | an external URL. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#documentation-layout |
# | |
# +--------------------------------------------------------------------------------------------------------+
nav:
- Home: index.md
- Profiles:
- profiles/index.md
- Formatting: profiles/formatting.md
- Placeholders: profiles/placeholders.md
- API: api.md
- API:
- api/index.md
- Changelog: api/changelog.md
- Examples: examples.md
- PlaceholderAPI: placeholderapi.md
# +--------------------------------------------------------------------------------------------------------+
# | |
# | The "theme" section allows you to define what theme to use. |
# | It is also used for theme-specific options, but also for advanced stuff such as theme-extensions, if |
# | the theme actually supports it. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#theme |
# | |
# +--------------------------------------------------------------------------------------------------------+
theme:
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "name" option is where you define the theme to use. |
# | |
# | Note that not all themes are included by default and will require you to install them first. |
# | The Material theme is one of them. See the "Read More" link for instructions on how to install it. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/getting-started/ |
# | |
# +------------------------------------------------------------------------------------------------------+
name: 'material'
# +------------------------------------------------------------------------------------------------------+
# | |
# | The Material theme allows "theme-extsnions", meaning that you can override parts of it by either |
# | overriding a particular file, or only parts (blocks) of it. |
# | |
# | If you want to override parts of Material, uncomment the "custom_dir" option below and set the |
# | folder (relative to the mkdocs.yml file) where your theme extensions will be located at. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#custom_dir |
# | - https://squidfunk.github.io/mkdocs-material/customization/#extending-the-theme |
# | |
# +------------------------------------------------------------------------------------------------------+
#custom_dir: 'theme'
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "favicon" option allows you to set your own image/icon to use in the browser-tab. |
# | |
# | Pretty much all image types are supported, but it's recommended to use a PNG, SVG or ICO image for |
# | the favicon. |
# | |
# | The directory is relative to the "docs_dir". |
# | |
# | Example: Having a favicon.png in docs/assets/images will result in the "favicon" setting showing |
# | 'assets/images/favicon.png' |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-logo-and-icons/#favicon |
# | |
# +------------------------------------------------------------------------------------------------------+
favicon: 'assets/images/favicon.png'
logo: 'assets/images/favicon.png'
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "palette" section is a Material option and allows you to define specific style options such as |
# | Color-Scheme, and primary and secondary Color. |
# | |
# | You can also define multiple palettes that can have different Color Schemses and primary and/or |
# | secondary Colors. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/ |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#color-palette-toggle |
# | |
# +------------------------------------------------------------------------------------------------------+
palette:
# +----------------------------------------------------------------------------------------------------+
# | |
# | The "scheme" option is used to define the Color Scheme used by Material. |
# | |
# | Material offers a "default" and a "slate" scheme. "default" is obviously the default (bright) |
# | Color scheme while "slate" is the native dark theme from Material. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#color-scheme |
# | |
# +----------------------------------------------------------------------------------------------------+
scheme: 'slate'
# +----------------------------------------------------------------------------------------------------+
# | |
# | "primary" is used to set the main color of the Material Theme. |
# | |
# | The primary color is used on the top banner of the page but also for things like the link color. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#primary-color |
# | |
# +----------------------------------------------------------------------------------------------------+
primary: 'indigo'
# +----------------------------------------------------------------------------------------------------+
# | |
# | The "accent" is used for moments such as hovering over links. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#accent-color |
# | |
# +----------------------------------------------------------------------------------------------------+
accent: 'indigo'
# +------------------------------------------------------------------------------------------------------+
# | |
# | With the "font" option can you set a different font to use. |
# | |
# | Material supports all Google fonts, but you can also define your own ones if you choose so. |
# | |
# | The "text" option is used for the regular font while "code" is used for code blocks, inline code and |
# | similar. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-fonts/ |
# | |
# +------------------------------------------------------------------------------------------------------+
#font:
# text: 'Roboto'
# code: 'Roboto Mono'
# +------------------------------------------------------------------------------------------------------+
# | |
# | Material suppors more than 40 different languages which you can set using the "language" option |
# | below. |
# | |
# | The default language is "en" (English). |
# | |
# | You can also enable/set a "selector" to allow switching between languages. |
# | See the "alternate" option in the "extra" section below for more information on this topic. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-language/ |
# | |
# +------------------------------------------------------------------------------------------------------+
#language: 'en'
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "direction" option is commonly used together with the "language" option. |
# | |
# | It allows you to change the text direction from the default left-to-right (ltr) to right-to-left |
# | (rtl) which is used in certain languages. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-language/#directionality |
# | |
# +------------------------------------------------------------------------------------------------------+
#direction: 'ltr'
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "features" option allows you to enable specific features of Material, by adding them to the |
# | list. |
# | |
# | Features are in the format <category>.<name>. As an example, the feature to enable tabs is called |
# | navigation.tabs. |
# | |
# | The list below contains all known features of Material. |
# | |
# | Features marked with a * are currently Insiders-only. (Last update: 11th December 2021) |
# | https://squidfunk.github.io/mkdocs-material/insiders/ |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/setting-up-navigation/ |
# | |
# +------------------------------------------------------------------------------------------------------+
features:
# Announce
#
#- announce.dismiss # Adds a "X" button to dismiss a news banner/mark it as read.*
# Header
#
#- header.autohide # Hide header when user scrolls past a specific point.
# Navigation:
#
#- navigation.expand # Expand all collapsable sections.
#- navigation.instant # Instant loading pages.
- navigation.indexes # Attach pages directly to Sections. Incompatible with "toc.integrate"
#- navigation.sections # Render top sections as groups.
- navigation.tabs # Render top sections as tabs at the top.
- navigation.tabs.sticky # Tabs won't disappear when scrolling down. Requires "navigation.tabs".
#- navigation.top # Adds a "Back to top" that is shown when scrolling up.
#- navigation.tracking # Updates the url with highlighted section anchor.
# Search
#
#- search.highlight # Search will highlight the searched word(s) on the page.*
#- search.share # Adds an option to share a search query link.*
#- search.suggest # Search will suggest the likeliest completion for a word.*
# Table of Contents
#
#- toc.integrate # Include the TOC sections in the left navugation.
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "icon" section allows you to define a icon to use for the logo and/or repository. |
# | |
# | To use already available icons will you need to set the right path for it, depending on which you |
# | want to use. |
# | |
# | Available icons: |
# | - FontAwesome |
# | - Brands: fontawesome/brands/... (https://fontawesome.com/icons?d=gallery&p=2&s=brands&m=free) |
# | - Regular: fontawesome/regular/... (https://fontawesome.com/icons?d=gallery&p=2&s=regular&m=free) |
# | - Solid: fontawesome/solid/... (https://fontawesome.com/icons?d=gallery&p=2&s=solid&m=free) |
# | |
# | - Material Design Icons: material/... (https://materialdesignicons.com/) |
# | |
# | - Octicons: octicons/... (https://primer.style/octicons/) |
# | |
# | You can also define your own Image for the logo. To do that, remove the "logo" option from "icon" |
# | instead add a "logo" option on the same level as the "icon" one, where you then set the path |
# | (relative to the "docs_dir") to the icon to use. Supported are all images types, including SVG. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-logo-and-icons/#logo |
# | |
# +------------------------------------------------------------------------------------------------------+
- navigation.indexes
- navigation.tabs
- navigation.tabs.sticky
icon:
repo: 'octicons/mark-github-16'
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "admonition" option allows you to set a different icon for each admonition type. |
# | |
# | This is currently a Insiders-only feature. (Last update: 7th October 2021) |
# | https://squidfunk.github.io/mkdocs-material/insiders/ |
# | |
# | Supported are all bundled icons: |
# | - FontAwesome |
# | - Brands: fontawesome/brands/... (https://fontawesome.com/icons?d=gallery&p=2&s=brands&m=free) |
# | - Regular: fontawesome/regular/... (https://fontawesome.com/icons?d=gallery&p=2&s=regular&m=free) |
# | - Solid: fontawesome/solid/... (https://fontawesome.com/icons?d=gallery&p=2&s=solid&m=free) |
# | |
# | - Material Design Icons: material/... (https://materialdesignicons.com/) |
# | |
# | - Octicons: octicons/... (https://primer.style/octicons/) |
# | |
# | You can also create and use your own icons. See the documentation for more information. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/reference/admonitions/#changing-the-icons |
# | |
# +------------------------------------------------------------------------------------------------------+
admonition:
note: 'octicons/tag-16'
abstract: 'octicons/checklist-16'
@@ -368,120 +52,24 @@ theme:
example: 'octicons/beaker-16'
quote: 'octicons/quote-16'
# +--------------------------------------------------------------------------------------------------------+
# | |
# | With the "extra_css" option can you add your own (S)CSS files to enhance the documentation. |
# | |
# | The path to the file is relative to the "docs_dir". |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#extra_css |
# | |
# +--------------------------------------------------------------------------------------------------------+
extra_css:
- assets/stylesheets/custom.css
# +--------------------------------------------------------------------------------------------------------+
# | |
# | Similar to the "extra_css" option does the "extra_javascript" option allow you to set custom JS files |
# | to add extra featurues. |
# | |
# | The path to the file is relative to the "docs_dir". |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#extra_javascript |
# | |
# +--------------------------------------------------------------------------------------------------------+
#extra_javascript:
# +--------------------------------------------------------------------------------------------------------+
# | |
# | The "extra" section contains pretty much anything you want, as long as it is a valid key-value pair. |
# | |
# | Material uses this section for different custom settings that wouldn't fit in the theme section. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#extra |
# | |
# +--------------------------------------------------------------------------------------------------------+
extra:
# +------------------------------------------------------------------------------------------------------+
# | |
# | The social section allows you to set a list of entries which would be displayed in the footer of the |
# | page. |
# | |
# | Each entry has the exact same options: |
# | - icon: Path to the SVG icon to use. See "icon" section for available icon sets. |
# | - link: URL to which the icon should link. |
# | - name: Optional Name that would be displayed as title on hover. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/setting-up-the-footer/#social-links |
# | |
# +------------------------------------------------------------------------------------------------------+
social:
- icon: 'fontawesome/brands/github'
link: 'https://github.com/Andre601/asl-wiki'
# +------------------------------------------------------------------------------------------------------+
# | |
# | Allows you to hide the "Made with Material for MkDocs" text in the footer of the pages by setting |
# | this to "true". |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/setting-up-the-footer/#generator-notice |
# | |
# +------------------------------------------------------------------------------------------------------+
#generator: true
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "manifest" option allows you to define a .manifest file to use. |
# | |
# | A .manifest file makes the doc act like a web-application and tells it how to behave when installed. |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/reference/meta-tags/#adding-a-web-app-manifest |
# | |
# +------------------------------------------------------------------------------------------------------+
#manifest: manifest.webmanifest
# +------------------------------------------------------------------------------------------------------+
# | |
# | The "alternate" option can be used to create a selector to switch languages. |
# | |
# | Using this requires you to create a specific, more complicated MkDocs setup. |
# | |
# | A Setup Guide for multi-language docs can be found here: |
# | https://github.com/squidfunk/mkdocs-material/discussions/2346 |
# | |
# | Read More: |
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-language/#site-language-selector |
# | |
# +------------------------------------------------------------------------------------------------------+
#alternate:
version:
provider: 'mike'
default:
- latest
- dev
# +--------------------------------------------------------------------------------------------------------+
# | |
# | MkDocs allows the usage of Markdown extensions which can do various things. |
# | |
# | Material includes the pymdownx extension which provides a lot of useful features to use. |
# | |
# | Note that some extensions may use specific settings that you need to set. |
# | Please check out the official documentation of PyMdownx for more information: |
# | https://facelessuser.github.io/pymdown-extensions/ |
# | |
# | Material already provides required CSS and JS values for the PyMdownX Extensions, which means you do |
# | not need to set them up yourself. |
# | |
# | Read More: |
# | - https://www.mkdocs.org/user-guide/configuration/#markdown_extensions |
# | |
# +--------------------------------------------------------------------------------------------------------+
markdown_extensions:
- markdown.extensions.admonition:
- markdown.extensions.toc:
permalink: true
- markdown.extensions.attr_list:
- pymdownx.emoji:
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg
@@ -1,195 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.paper;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import ch.andre601.advancedserverlist.paper.commands.CmdAdvancedServerList;
import ch.andre601.advancedserverlist.paper.events.JoinEvent;
import ch.andre601.advancedserverlist.paper.events.PingEvent;
import ch.andre601.advancedserverlist.paper.logging.PaperLogger;
import ch.andre601.advancedserverlist.paper.objects.PaperPlayer;
import ch.andre601.advancedserverlist.paper.objects.PlayerPlaceholders;
import com.destroystokyo.paper.profile.PlayerProfile;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie;
import org.bukkit.Bukkit;
import org.bukkit.command.PluginCommand;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.CachedServerIcon;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon, PlayerProfile, PaperPlayer>{
private final PluginLogger logger = new PaperLogger(getLogger());
private AdvancedServerList core;
private FaviconHandler<CachedServerIcon> faviconHandler;
@Override
public void onEnable(){
try{
Class.forName("io.papermc.paper.configuration.ConfigurationLoaders");
enable();
}catch(ClassNotFoundException ex){
try{
Class.forName("com.destroystokyo.paper.PaperConfig");
enable();
}catch(ClassNotFoundException ex1){
printSpigotWarning();
getServer().getPluginManager().disablePlugin(this);
}
}
}
@Override
public void onDisable(){
if(getCore() == null)
return; // This is always the case when the plugin is used on a Spigot server (See above try-catch blocks).
getCore().disable();
}
@Override
public void loadCommands(){
PluginCommand cmd = getServer().getPluginCommand("advancedserverlist");
if(cmd == null){
getPluginLogger().warn("Could not register command /advancedserverlist");
return;
}
cmd.setExecutor(new CmdAdvancedServerList(this));
}
@Override
public void loadEvents(){
new JoinEvent(this);
new PingEvent(this);
}
@Override
public void loadMetrics(){
new Metrics(this, 15584).addCustomChart(new SimplePie("profiles",
() -> String.valueOf(core.getFileHandler().getProfiles().size())
));
}
@Override
public void clearFaviconCache(){
if(faviconHandler == null)
return;
faviconHandler.clearCache();
}
@Override
public AdvancedServerList getCore(){
return core;
}
@Override
public Path getFolderPath(){
return getDataFolder().toPath();
}
@Override
public PluginLogger getPluginLogger(){
return logger;
}
@Override
public FaviconHandler<CachedServerIcon> getFaviconHandler(){
if(faviconHandler == null)
faviconHandler = new FaviconHandler<>(core);
return faviconHandler;
}
@Override
public String getPlatformName(){
return getServer().getName();
}
@Override
public String getPlatformVersion(){
return getServer().getVersion();
}
@Override
public String getLoader(){
return "paper";
}
@Override
public List<PlayerProfile> createPlayers(List<String> lines, PaperPlayer player, GenericServer server){
List<PlayerProfile> players = new ArrayList<>(lines.size());
for(String line : lines){
String parsed = ComponentParser.text(line)
.applyReplacements(player, server)
.modifyText(text -> {
if(getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
return text;
})
.toString();
players.add(Bukkit.createProfile(UUID.randomUUID(), parsed));
}
return players;
}
private void enable(){
this.core = new AdvancedServerList(this, new PlayerPlaceholders());
}
private void printSpigotWarning(){
getPluginLogger().warn("======================================== WARNING ========================================");
getPluginLogger().warn("");
getPluginLogger().warn("You are using the Paper version of AdvancedServerList on a SpigotMC server.");
getPluginLogger().warn("The Paper version is ONLY compatible with Paper itself due to it using exclusive");
getPluginLogger().warn("methods and events not available within SpigotMC.");
getPluginLogger().warn("");
getPluginLogger().warn("To avoid any exceptions and errors will AdvancedServerList disable itself now.");
getPluginLogger().warn("Please stop your server and either switch to Paper or use the Spigot version");
getPluginLogger().warn("of AdvancedServerList.");
getPluginLogger().warn("");
getPluginLogger().warn("Paper can be downloaded here:");
getPluginLogger().warn("https://papermc.io/downloads");
getPluginLogger().warn("");
getPluginLogger().warn("======================================== WARNING ========================================");
}
}
@@ -1,48 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.paper.commands;
import ch.andre601.advancedserverlist.paper.PaperCore;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public class CmdAdvancedServerList implements CommandExecutor{
private final PaperCore plugin;
public CmdAdvancedServerList(PaperCore plugin){
this.plugin = plugin;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, @NotNull String[] args){
plugin.getCore().getCommandHandler().handle(new PaperCmdSender(sender), args);
return true;
}
}
@@ -1,54 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.paper.events;
import ch.andre601.advancedserverlist.paper.PaperCore;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import java.net.InetSocketAddress;
public class JoinEvent implements Listener{
private final PaperCore plugin;
public JoinEvent(PaperCore plugin){
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onJoin(PlayerJoinEvent event){
InetSocketAddress address = event.getPlayer().getAddress();
if(address == null)
return;
Player player = event.getPlayer();
plugin.getCore().getPlayerHandler().addPlayer(address.getHostString(), player.getName(), player.getUniqueId());
}
}
@@ -1,60 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.paper.logging;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import java.util.logging.Level;
import java.util.logging.Logger;
public class PaperLogger implements PluginLogger{
private final Logger logger;
public PaperLogger(Logger logger){
this.logger = logger;
}
@Override
public void info(String msg, Object... args){
logger.info(String.format(msg, args));
}
@Override
public void warn(String msg, Object... args){
logger.warning(String.format(msg, args));
}
@Override
public void warn(String msg, Throwable throwable){
logger.log(Level.WARNING, msg, throwable);
}
@Override
public void warn(String msg, Throwable throwable, Object... args){
logger.log(Level.WARNING, String.format(msg, args), throwable);
}
}
@@ -1,54 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.paper.objects;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import org.bukkit.OfflinePlayer;
public class PaperPlayer extends GenericPlayer{
private final OfflinePlayer player;
public PaperPlayer(OfflinePlayer player, CachedPlayer cachedPlayer, int protocol){
this.player = player;
this.name = player == null ? cachedPlayer.getName() : player.getName();
this.protocol = protocol;
this.uuid = player == null ? cachedPlayer.getUuid() : player.getUniqueId();
if(player == null)
return;
this.playedBefore = player.hasPlayedBefore();
this.banned = player.isBanned();
this.whitelisted = player.isWhitelisted();
}
public OfflinePlayer getPlayer(){
return player;
}
}
@@ -1,56 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* 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 ch.andre601.advancedserverlist.paper.objects;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
public class PlayerPlaceholders extends PlaceholderProvider{
public PlayerPlaceholders(){
super("player");
}
@Override
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
PaperPlayer paperPlayer = (PaperPlayer)player;
return switch(placeholder){
case "name" -> paperPlayer.getName();
case "protocol" -> String.valueOf(paperPlayer.getProtocol());
case "uuid" -> String.valueOf(paperPlayer.getUUID());
case "hasPlayedBefore" -> returnValue(paperPlayer, player.hasPlayedBefore());
case "isBanned" -> returnValue(paperPlayer, player.isBanned());
case "isWhitelisted" -> returnValue(paperPlayer, player.isWhitelisted());
default -> null;
};
}
private String returnValue(PaperPlayer player, Object value){
return player.getPlayer() == null ? null : String.valueOf(value);
}
}
+13 -5
View File
@@ -37,19 +37,27 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<plugin.version>2.0.0</plugin.version>
<plugin.version>3.0.0</plugin.version>
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
<api.version>v2.1.0</api.version>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>jitpack</id>
<url>https://jitpack.io/</url>
</repository>
</repositories>
<modules>
<module>api</module>
<module>core</module>
<module>bungeecord</module>
<module>paper</module>
<module>spigot</module>
<module>bukkit</module>
<module>velocity</module>
<module>hangar-uploader</module>
</modules>
</project>
+1 -1
View File
@@ -1 +1 @@
mkdocs-material==9.0.6
mkdocs-material==9.1.5
+20 -6
View File
@@ -57,6 +57,12 @@
<version>${plugin.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>platform-velocity</artifactId>
<version>${api.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.velocitypowered</groupId>
<artifactId>velocity-api</artifactId>
@@ -66,7 +72,19 @@
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-velocity</artifactId>
<version>3.0.0</version>
<version>3.0.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.spongepowered</groupId>
<artifactId>configurate-yaml</artifactId>
<version>4.1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
@@ -83,7 +101,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<version>3.11.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -100,10 +118,6 @@
<pattern>org.bstats</pattern>
<shadedPattern>ch.andre601.advancedserverlist.velocity.depends.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>com.github.benmanes.caffeine</pattern>
<shadedPattern>ch.andre601.advancedserverlist.velocity.depends.caffeine</shadedPattern>
</relocation>
<relocation>
<pattern>okhttp3</pattern>
<shadedPattern>ch.andre601.advancedserverlist.velocity.depends.okhttp3</shadedPattern>
@@ -25,18 +25,15 @@
package ch.andre601.advancedserverlist.velocity;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import ch.andre601.advancedserverlist.velocity.commands.CmdAdvancedServerList;
import ch.andre601.advancedserverlist.velocity.events.JoinEvent;
import ch.andre601.advancedserverlist.velocity.events.PingEvent;
import ch.andre601.advancedserverlist.velocity.logging.VelocityLogger;
import ch.andre601.advancedserverlist.velocity.objects.PlayerPlaceholders;
import ch.andre601.advancedserverlist.velocity.objects.VelocityPlayer;
import ch.andre601.advancedserverlist.velocity.objects.VelocityPlayerPlaceholders;
import com.google.inject.Inject;
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.event.Subscribe;
@@ -44,18 +41,14 @@ import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.server.ServerPing;
import com.velocitypowered.api.util.Favicon;
import org.bstats.charts.SimplePie;
import org.bstats.velocity.Metrics;
import org.slf4j.LoggerFactory;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class VelocityCore implements PluginCore<Favicon, ServerPing.SamplePlayer, VelocityPlayer>{
public class VelocityCore implements PluginCore<Favicon>{
private final PluginLogger logger;
private final ProxyServer proxy;
@@ -76,7 +69,7 @@ public class VelocityCore implements PluginCore<Favicon, ServerPing.SamplePlayer
@Subscribe
public void init(ProxyInitializeEvent event){
this.core = new AdvancedServerList(this, new PlayerPlaceholders());
this.core = new AdvancedServerList(this, new VelocityPlayerPlaceholders());
}
@Subscribe
@@ -138,21 +131,6 @@ public class VelocityCore implements PluginCore<Favicon, ServerPing.SamplePlayer
return faviconHandler;
}
@Override
public List<ServerPing.SamplePlayer> createPlayers(List<String> lines, VelocityPlayer player, GenericServer server){
List<ServerPing.SamplePlayer> players = new ArrayList<>(lines.size());
for(String line : lines){
String parsed = ComponentParser.text(line)
.applyReplacements(player, server)
.toString();
players.add(new ServerPing.SamplePlayer(parsed, UUID.randomUUID()));
}
return players;
}
@Override
public String getPlatformName(){
return getProxy().getVersion().getName();
@@ -25,7 +25,7 @@
package ch.andre601.advancedserverlist.velocity.commands;
import ch.andre601.advancedserverlist.core.interfaces.CmdSender;
import ch.andre601.advancedserverlist.core.interfaces.commands.CmdSender;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import com.velocitypowered.api.command.CommandSource;
@@ -23,15 +23,12 @@
*
*/
package ch.andre601.advancedserverlist.core.interfaces;
package ch.andre601.advancedserverlist.velocity.events;
public interface CmdSender{
boolean hasPermission(String permission);
default void sendMsg(){
sendMsg("");
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
public class PreServerListSetEventImpl extends PreServerListSetEvent{
public PreServerListSetEventImpl(ProfileEntry entry){
super(entry);
}
void sendMsg(String msg, Object... args);
}
@@ -25,12 +25,16 @@
package ch.andre601.advancedserverlist.velocity.events;
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.velocity.VelocityCore;
import ch.andre601.advancedserverlist.velocity.objects.VelocityPlayer;
import ch.andre601.advancedserverlist.velocity.objects.VelocityPlayerImpl;
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
import com.velocitypowered.api.proxy.server.ServerPing;
import com.velocitypowered.api.util.Favicon;
@@ -38,8 +42,10 @@ import net.kyori.adventure.text.Component;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
public class VelocityEventWrapper implements GenericEventWrapper<Favicon, ServerPing.SamplePlayer, VelocityPlayer>{
public class VelocityEventWrapper implements GenericEventWrapper<Favicon, VelocityPlayerImpl>{
private final VelocityCore plugin;
private final ProxyPingEvent event;
@@ -53,6 +59,18 @@ public class VelocityEventWrapper implements GenericEventWrapper<Favicon, Server
this.protocol = event.getPing().getVersion();
}
@Override
public GenericServerListEvent callEvent(ProfileEntry entry){
PreServerListSetEventImpl event = new PreServerListSetEventImpl(entry);
try{
plugin.getProxy().getEventManager().fire(event).get();
}catch(InterruptedException | ExecutionException ignored){
return null;
}
return event;
}
@Override
public void setMaxPlayers(int maxPlayers){
builder.maximumPlayers(maxPlayers);
@@ -74,12 +92,19 @@ public class VelocityEventWrapper implements GenericEventWrapper<Favicon, Server
}
@Override
public void setPlayers(List<String> players, VelocityPlayer player, GenericServer server){
ServerPing.SamplePlayer[] playerSamples = plugin.createPlayers(players, player, server)
.toArray(new ServerPing.SamplePlayer[0]);
public void setPlayers(List<String> lines, VelocityPlayerImpl player, GenericServer server){
ServerPing.SamplePlayer[] players = new ServerPing.SamplePlayer[lines.size()];
if(playerSamples.length > 0)
builder.clearSamplePlayers().samplePlayers(playerSamples);
for(int i = 0; i < players.length; i++){
String parsed = ComponentParser.text(lines.get(i))
.modifyText(text -> StringReplacer.replace(text, player, server))
.toString();
players[i] = new ServerPing.SamplePlayer(parsed, UUID.randomUUID());
}
if(players.length > 0)
builder.clearSamplePlayers().samplePlayers(players);
}
@Override
@@ -122,7 +147,7 @@ public class VelocityEventWrapper implements GenericEventWrapper<Favicon, Server
}
@Override
public String parsePAPIPlaceholders(String text, VelocityPlayer player){
public String parsePAPIPlaceholders(String text, VelocityPlayerImpl player){
return text;
}
@@ -132,13 +157,13 @@ public class VelocityEventWrapper implements GenericEventWrapper<Favicon, Server
}
@Override
public PluginCore<Favicon, ServerPing.SamplePlayer, VelocityPlayer> getPlugin(){
public PluginCore<Favicon> getPlugin(){
return plugin;
}
@Override
public VelocityPlayer createPlayer(CachedPlayer player, int protocol){
return new VelocityPlayer(player, protocol);
public VelocityPlayerImpl createPlayer(CachedPlayer player, int protocol){
return new VelocityPlayerImpl(player, protocol);
}
@Override
@@ -25,17 +25,23 @@
package ch.andre601.advancedserverlist.velocity.objects;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayerImpl;
import com.velocitypowered.api.network.ProtocolVersion;
public class VelocityPlayer extends GenericPlayer{
public class VelocityPlayerImpl extends GenericPlayerImpl implements VelocityPlayer{
public VelocityPlayer(CachedPlayer player, int protocol){
private final String version;
public VelocityPlayerImpl(CachedPlayer player, int protocol){
this.name = player.getName();
this.protocol = protocol;
this.uuid = player.getUuid();
this.version = ProtocolVersion.getProtocolVersion(protocol).getVersionIntroducedIn();
}
@Override
public String getVersion(){
return version;
}
}
@@ -29,9 +29,9 @@ import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
public class PlayerPlaceholders extends PlaceholderProvider{
public class VelocityPlayerPlaceholders extends PlaceholderProvider{
public PlayerPlaceholders(){
public VelocityPlayerPlaceholders(){
super("player");
}
@@ -41,7 +41,7 @@ public class PlayerPlaceholders extends PlaceholderProvider{
case "name" -> player.getName();
case "protocol" -> String.valueOf(player.getProtocol());
case "uuid" -> String.valueOf(player.getUUID());
case "version" -> player.getVersion();
case "version" -> ((VelocityPlayerImpl)player).getVersion();
default -> null;
};
}