Compare commits

...
120 Commits
Author SHA1 Message Date
Andre_601 3859f2970f Merge pull request #41 from Andre601/feature/uuid-usage
Improve player caching behaviour
2023-01-10 20:36:34 +01:00
Andre601 71079bf9d8 Bump version 2023-01-09 20:47:46 +01:00
Andre601 4fa7e92264 Make CachedPlayer its own class 2023-01-09 20:46:46 +01:00
Andre_601 828d907371 Merge branch 'master' into feature/uuid-usage 2023-01-09 20:37:36 +01:00
Andre601 986c36a334 tiny typo fix 2023-01-09 20:36:08 +01:00
Andre_601 8f9ae4a835 Merge pull request #43 from Andre601/fix/nullpointerexceptions
Fix some NullPointerExceptions
2023-01-09 20:32:01 +01:00
Andre601 0dccdaf7e4 Add a comment 2023-01-09 20:31:31 +01:00
Andre601 ec0dec8e7d Try to fix errors with OkHttpClient 2023-01-09 17:59:23 +01:00
Andre601 f399ed6886 Fix some NullPointerExceptions 2023-01-09 17:42:54 +01:00
Andre_601 f2737f2b19 Merge pull request #42 from Andre601/dependabot/maven/core/com.google.code.gson-gson-2.10.1
Bump gson from 2.10 to 2.10.1 in /core
2023-01-09 16:20:46 +01:00
dependabot[bot] 504e669ce7 Bump gson from 2.10 to 2.10.1 in /core
Bumps [gson](https://github.com/google/gson) from 2.10 to 2.10.1.
- [Release notes](https://github.com/google/gson/releases)
- [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/gson/compare/gson-parent-2.10...gson-parent-2.10.1)

---
updated-dependencies:
- dependency-name: com.google.code.gson:gson
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-09 15:16:41 +00:00
Andre601 0cae58c9b6 Update Copyright 2023-01-01 00:33:39 +01:00
Andre601 91dcb49e81 Update log messages 2022-12-31 16:40:57 +01:00
Andre601 c8a1224f53 Fix broken logic and make ${player uuid} always available 2022-12-31 16:21:26 +01:00
Andre601 5722700d20 Improve player caching behaviour 2022-12-31 01:25:57 +01:00
Andre_601 1effc2574a Update release.yml 2022-12-28 20:15:16 +01:00
Andre_601 eb7a7fa6c7 Delete prerelease.yml 2022-12-28 20:15:07 +01:00
Andre601 9f6bdea168 Add better Version check (+ tests) 2022-12-28 16:58:23 +01:00
Andre_601 d247d832e6 Update prerelease.yml 2022-12-27 22:02:32 +01:00
Andre_601 708037bb6b Update release.yml 2022-12-27 22:02:05 +01:00
Andre_601 7da88771b6 Update prerelease.yml 2022-12-27 21:27:01 +01:00
Andre_601 9ccfd4674c Add workflow for beta-releases 2022-12-27 21:26:16 +01:00
Andre_601 9054ebdb0c Merge pull request #40 from Andre601/feature/multi-profiles
Implement system for multiple profiles in profiles
2022-12-27 21:22:25 +01:00
Andre601 edfd77e891 Fix wrong hidePlayersEnabled call. 2022-12-27 21:19:01 +01:00
Andre601 94391a8aed Make booleans and int nullable + version bump 2022-12-27 21:16:23 +01:00
Andre601 5a1f343cc2 Update config.yml 2022-12-27 18:03:07 +01:00
Andre601 e718a5c766 Improve descriptions 2022-12-27 18:01:40 +01:00
Andre601 565644ccd5 Add profiles example 2022-12-27 17:51:07 +01:00
Andre601 9531af1fdd Don't use random on a single entry 2022-12-27 16:56:50 +01:00
Andre601 7c1d7aadbc Try a system with fallback to def profile 2022-12-27 16:46:02 +01:00
Andre601 f26f2ba269 Implement system for multiple profiles in profiles 2022-12-27 16:03:01 +01:00
Andre_601 f5d2fd1534 Merge pull request #39 from Andre601/feature/multiple-motds
Add option to have multiple MOTDs.
2022-12-20 22:22:49 +01:00
Andre601 90537eb004 Bump Version for release 2022-12-20 22:22:14 +01:00
Andre601 ce6a9e3b0b Use a Builder class to make ServerListProfile immutable... I guess? 2022-12-18 21:32:35 +01:00
Andre601 4d29f9e45e Add option to have multiple MOTDs. 2022-12-18 17:45:38 +01:00
Andre601 bf49636d6a Update workflow 2022-12-09 22:27:44 +01:00
Andre601 4a6c9a55d4 Update required libraries 2022-12-09 22:26:44 +01:00
Andre601 a5bfc0b6e3 Smaller format correction + version bump 2022-12-09 22:23:24 +01:00
Andre_601 dff332a83a Merge pull request #37 from Andre601/dependabot/maven/spigot/net.kyori-adventure-platform-bukkit-4.2.0
Bump adventure-platform-bukkit from 4.1.2 to 4.2.0 in /spigot
2022-12-09 16:10:29 +01:00
dependabot[bot] 58a16baaab Bump adventure-platform-bukkit from 4.1.2 to 4.2.0 in /spigot
Bumps [adventure-platform-bukkit](https://github.com/KyoriPowered/adventure-platform) from 4.1.2 to 4.2.0.
- [Release notes](https://github.com/KyoriPowered/adventure-platform/releases)
- [Commits](https://github.com/KyoriPowered/adventure-platform/compare/v4.1.2...v4.2.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>
2022-12-09 15:08:40 +00:00
Andre_601 c8acb4d90a Merge pull request #36 from Andre601/feature/unified-eventhandler
Create unified EventHandler
2022-12-08 21:56:48 +01:00
Andre_601 5575243a79 Merge pull request #35 from Andre601/dependabot/maven/core/com.google.code.gson-gson-2.10
Bump gson from 2.9.1 to 2.10 in /core
2022-12-08 16:43:13 +01:00
Andre601 4cd4aeb12a Move Favicon creation and logging to PingEventHandler 2022-12-08 16:42:23 +01:00
Andre601 5922b2235e Bump version 2022-12-07 21:19:23 +01:00
Andre601 2fcef08f5a Wrap up (no pun intended) remaining platform events 2022-12-07 16:28:39 +01:00
Andre601 30c28b07a4 Smaller changes 2022-12-06 21:32:16 +01:00
Andre601 08b4f1029c Make Protocol and ServerPing final 2022-12-06 21:27:09 +01:00
Andre601 f5051022aa Create unified EventHandler 2022-12-06 21:24:43 +01:00
dependabot[bot] fe51e78764 Bump gson from 2.9.1 to 2.10 in /core
Bumps [gson](https://github.com/google/gson) from 2.9.1 to 2.10.
- [Release notes](https://github.com/google/gson/releases)
- [Changelog](https://github.com/google/gson/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/gson/compare/gson-parent-2.9.1...gson-parent-2.10)

---
updated-dependencies:
- dependency-name: com.google.code.gson:gson
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-06 15:11:07 +00:00
Andre_601 5b2d9d910f Use env variables 2022-12-06 14:17:34 +01:00
Andre_601 6f06c47de7 Merge pull request #34 from Andre601/feature/update-checker
Add Update Checker
2022-12-06 14:03:25 +01:00
Andre601 ad3ba0c8b3 Update config description 2022-12-06 00:49:52 +01:00
Andre601 12d8d930dd Use a ScheduledExecutorService instead of Timer 2022-12-06 00:26:55 +01:00
Andre601 9a30a6b679 Add info line 2022-12-06 00:01:24 +01:00
Andre601 b82cf69d43 Simplify more. 2022-12-05 23:58:05 +01:00
Andre601 fb6d93b455 Init timer only when UpdateChecker is used. 2022-12-05 23:55:54 +01:00
Andre601 a1276da68f Fix exceptions 2022-12-05 23:13:21 +01:00
Andre601 25c053d495 Use timer class from Java 2022-12-05 22:24:19 +01:00
Andre601 39c1fb5452 Better version comparison. 2022-12-05 21:26:24 +01:00
Andre601 48edebc043 Add config option 2022-12-03 20:29:45 +01:00
Andre601 3a672378ff Add Update Checker 2022-12-03 20:23:21 +01:00
Andre_601 9db9f2be7f Merge pull request #33 from Andre601/dependabot/maven/core/net.kyori-adventure-api-4.12.0
Bump adventure-api from 4.11.0 to 4.12.0 in /core
2022-11-28 16:31:53 +01:00
Andre_601 2cf47e351b Merge pull request #32 from Andre601/dependabot/maven/core/net.kyori-adventure-text-minimessage-4.12.0
Bump adventure-text-minimessage from 4.11.0 to 4.12.0 in /core
2022-11-28 16:31:39 +01:00
Andre_601 36abdb83cd Merge pull request #31 from Andre601/dependabot/maven/core/net.kyori-adventure-text-serializer-legacy-4.12.0
Bump adventure-text-serializer-legacy from 4.11.0 to 4.12.0 in /core
2022-11-28 16:31:21 +01:00
dependabot[bot] ad950bf330 Bump adventure-api from 4.11.0 to 4.12.0 in /core
Bumps [adventure-api](https://github.com/KyoriPowered/adventure) from 4.11.0 to 4.12.0.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.11.0...v4.12.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>
2022-11-28 15:12:17 +00:00
dependabot[bot] 143753d309 Bump adventure-text-minimessage from 4.11.0 to 4.12.0 in /core
Bumps [adventure-text-minimessage](https://github.com/KyoriPowered/adventure) from 4.11.0 to 4.12.0.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.11.0...v4.12.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>
2022-11-28 15:12:10 +00:00
dependabot[bot] 0c37c21650 Bump adventure-text-serializer-legacy from 4.11.0 to 4.12.0 in /core
Bumps [adventure-text-serializer-legacy](https://github.com/KyoriPowered/adventure) from 4.11.0 to 4.12.0.
- [Release notes](https://github.com/KyoriPowered/adventure/releases)
- [Commits](https://github.com/KyoriPowered/adventure/compare/v4.11.0...v4.12.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>
2022-11-28 15:12:04 +00:00
Andre_601 40a6b4f059 Merge pull request #30 from Andre601/dependabot/maven/core/com.github.ben-manes.caffeine-caffeine-3.1.2
Bump caffeine from 3.1.1 to 3.1.2 in /core
2022-11-24 16:24:36 +01:00
dependabot[bot] 965e87d71b Bump caffeine from 3.1.1 to 3.1.2 in /core
Bumps [caffeine](https://github.com/ben-manes/caffeine) from 3.1.1 to 3.1.2.
- [Release notes](https://github.com/ben-manes/caffeine/releases)
- [Commits](https://github.com/ben-manes/caffeine/compare/v3.1.1...v3.1.2)

---
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>
2022-11-24 15:08:34 +00:00
Andre_601 202a22f33a Update README.md 2022-11-21 15:20:02 +01:00
Andre_601 a4b2a6c350 Update MODRINTH.md 2022-11-21 15:03:28 +01:00
Andre601 ba55f5299b Bump version 2022-11-07 22:29:04 +01:00
Andre_601 24fdf798cf Merge pull request #29 from Andre601/feature/disable-cache-option
Add option to disable Cache
2022-11-07 22:28:16 +01:00
Andre601 e208d181b7 Add option to disable Cache 2022-11-07 22:14:50 +01:00
Andre_601 6c15c7b259 Merge pull request #28 from Andre601/dependabot/maven/paper/org.apache.maven.plugins-maven-shade-plugin-3.4.1
Bump maven-shade-plugin from 3.4.0 to 3.4.1 in /paper
2022-10-27 17:55:21 +02:00
Andre_601 dcd76a43f5 Merge pull request #27 from Andre601/dependabot/maven/bungeecord/org.apache.maven.plugins-maven-shade-plugin-3.4.1
Bump maven-shade-plugin from 3.4.0 to 3.4.1 in /bungeecord
2022-10-27 17:55:10 +02:00
Andre_601 adc2060499 Merge pull request #26 from Andre601/dependabot/maven/velocity/org.apache.maven.plugins-maven-shade-plugin-3.4.1
Bump maven-shade-plugin from 3.4.0 to 3.4.1 in /velocity
2022-10-27 17:55:01 +02:00
Andre_601 4d6befc857 Merge pull request #25 from Andre601/dependabot/maven/core/org.apache.maven.plugins-maven-shade-plugin-3.4.1
Bump maven-shade-plugin from 3.4.0 to 3.4.1 in /core
2022-10-27 17:54:52 +02:00
dependabot[bot] 7cfb792471 Bump maven-shade-plugin from 3.4.0 to 3.4.1 in /paper
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>
2022-10-27 15:41:21 +00:00
dependabot[bot] d46245eefa Bump maven-shade-plugin from 3.4.0 to 3.4.1 in /bungeecord
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>
2022-10-27 15:41:17 +00:00
dependabot[bot] d5e0fd3d7a Bump maven-shade-plugin from 3.4.0 to 3.4.1 in /velocity
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>
2022-10-27 15:41:11 +00:00
dependabot[bot] 496e246b9e Bump maven-shade-plugin from 3.4.0 to 3.4.1 in /core
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>
2022-10-27 15:41:11 +00:00
Andre_601 e263a45f1c width and not height 2022-10-05 17:40:40 +02:00
Andre_601 edfc977730 Update MODRINTH.md 2022-10-05 17:40:01 +02:00
Andre_601 5910c26b4b Add waterfall badge 2022-10-03 23:49:07 +02:00
Andre_601 5b9c506a89 Use jsdelivr url 2022-09-26 00:17:47 +02:00
Andre_601 913ddd7834 Create MODRINTH.md 2022-09-22 13:41:05 +02:00
Andre_601 397c7ea59a Merge pull request #23 from Andre601/feature/readme-new-badges
Prepare readme for new badges
2022-09-21 01:48:30 +02:00
Andre_601 6e7b2541e1 Update README.md 2022-09-21 01:48:22 +02:00
Andre_601 241c15a452 Update README.md 2022-09-20 22:07:40 +02:00
Andre_601 62c5d13aa2 Prepare readme for new badges 2022-09-20 22:05:33 +02:00
Andre601 3a73c5ce6b Fix wrong open-perms for certain OS 2022-09-20 00:41:33 +02:00
Andre_601 bf54e8eb0b Yes I update the README a lot today... 2022-09-18 01:45:46 +02:00
Andre_601 aa2cabedbf Update README.md 2022-09-18 01:09:01 +02:00
Andre_601 66878626e1 Update README.md 2022-09-17 23:35:34 +02:00
Andre_601 f6f3f3d8b6 Update README.md 2022-09-17 23:25:48 +02:00
Andre601 85e41b6c7e Fix wrong formatted messages in /asl reload 2022-09-17 22:51:33 +02:00
Andre_601 a220efc624 Update README.md 2022-09-17 17:58:49 +02:00
Andre_601 ea8871ce8f Update README.md 2022-09-17 17:50:32 +02:00
Andre_601 ea0fdc3798 Update README.md 2022-09-17 17:50:06 +02:00
Andre_601 1188ab0c9c Create config.yml 2022-09-15 01:52:30 +02:00
Andre_601 aaefd4c928 Create feature_request.yml 2022-09-15 01:50:28 +02:00
Andre_601 940bf2fb9d fix typo 2022-09-15 01:20:23 +02:00
Andre_601 0c24bf8d24 Update bug_report.yml 2022-09-15 01:19:36 +02:00
Andre_601 564ce7a820 Create bug_report.yml 2022-09-15 01:18:54 +02:00
Andre_601 bb8cd21b86 Merge pull request #22 from Andre601/dependabot/maven/velocity/org.apache.maven.plugins-maven-shade-plugin-3.4.0
Bump maven-shade-plugin from 3.3.0 to 3.4.0 in /velocity
2022-09-14 18:33:57 +02:00
Andre_601 2d2d8a6175 Merge pull request #20 from Andre601/dependabot/maven/bungeecord/org.apache.maven.plugins-maven-shade-plugin-3.4.0
Bump maven-shade-plugin from 3.3.0 to 3.4.0 in /bungeecord
2022-09-14 18:33:48 +02:00
Andre_601 fcd4bdbe14 Merge pull request #19 from Andre601/dependabot/maven/paper/org.apache.maven.plugins-maven-shade-plugin-3.4.0
Bump maven-shade-plugin from 3.3.0 to 3.4.0 in /paper
2022-09-14 18:33:37 +02:00
Andre_601 3a9b2a7c5a Merge pull request #18 from Andre601/dependabot/maven/core/org.apache.maven.plugins-maven-shade-plugin-3.4.0
Bump maven-shade-plugin from 3.3.0 to 3.4.0 in /core
2022-09-14 18:33:27 +02:00
dependabot[bot] 3b3793ab9a Bump maven-shade-plugin from 3.3.0 to 3.4.0 in /velocity
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.3.0...maven-shade-plugin-3.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-14 16:33:17 +00:00
Andre_601 d679694d6e Merge pull request #21 from Andre601/dependabot/maven/spigot/org.apache.maven.plugins-maven-shade-plugin-3.4.0
Bump maven-shade-plugin from 3.3.0 to 3.4.0 in /spigot
2022-09-14 18:33:09 +02:00
dependabot[bot] 47405f7492 Bump maven-shade-plugin from 3.3.0 to 3.4.0 in /spigot
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.3.0...maven-shade-plugin-3.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-14 16:31:57 +00:00
dependabot[bot] af7408dcd5 Bump maven-shade-plugin from 3.3.0 to 3.4.0 in /bungeecord
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.3.0...maven-shade-plugin-3.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-14 16:31:30 +00:00
dependabot[bot] 17d0930195 Bump maven-shade-plugin from 3.3.0 to 3.4.0 in /paper
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.3.0...maven-shade-plugin-3.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-14 16:31:28 +00:00
dependabot[bot] 91cd3b6032 Bump maven-shade-plugin from 3.3.0 to 3.4.0 in /core
Bumps [maven-shade-plugin](https://github.com/apache/maven-shade-plugin) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/apache/maven-shade-plugin/releases)
- [Commits](https://github.com/apache/maven-shade-plugin/compare/maven-shade-plugin-3.3.0...maven-shade-plugin-3.4.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-14 16:31:26 +00:00
Andre601 2d67145ae5 Bump version 2022-09-09 23:33:22 +02:00
Andre601 ba1dd8a70d Fix clearFaviconCache() + expression error 2022-09-09 23:33:00 +02:00
Andre_601 4ea77f2907 Update README.md 2022-09-09 15:11:42 +02:00
Andre_601 7fdc23baa1 Update release.yml 2022-09-09 14:52:13 +02:00
Andre601 d630b472ca Simplify validation check 2022-09-09 01:39:15 +02:00
80 changed files with 2683 additions and 785 deletions

No files matched your search

+62
View File
@@ -0,0 +1,62 @@
name: Bug Report
description: Report an issue with the plugin
body:
- type: markdown
attributes:
value: |-
## Before opening
Please make sure you've checked the following things first:
- You're using the latest release of AdvancedServerList [[Download from Modrinth](https://modrinth.com/plugin/advancedserverlist)]
- You're using a supported Proxy/Server version. As of right now is only 1.19.x supported.
- The issue happens with just AdvancedServerList installed.
- type: dropdown
attributes:
label: Platform
description: On what platform do you use the plugin?
options:
- BungeeCord
- Other (Please specify)
- Paper
- Purpur
- Spigot
- Velocity
- Waterfall
validations:
required: true
- type: input
attributes:
label: Other platform
description: |-
Please provide the name of the platform (Proxy/Server) you use, if you selected `Other (Please specify)` in the above section.
Leave empty otherwise.
placeholder: SomeProxy
- type: textarea
attributes:
label: What happened?
description: |-
Give a detailed description of what exactly happened.
You can provide screenshots to further explain the issues.
When sharing errors, make sure to use a site such as https://paste.helpch.at to do so.
placeholder: When I do ... does ... happen.
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: Provide a detailed step-by-step explanation on how to reproduce this issue.
placeholder: |-
1. Do this
2. ...
3. Profit!
validations:
required: true
- type: textarea
attributes:
label: Server List Profiles
description: |-
**Optional**
Provide any Server List Profiles you use, if you believe those to be the cause of the issue.
This text field will automatically render the text as YAML code.
render: yaml
+8
View File
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Discord Server
about: Ask questions about the plugin in the `#advancedserverlist` channel.
url: https://discord.gg/6dazXp6
- name: Wiki
about: Check the Wiki for explanations about the features and examples.
url: https://github.com/Andre601/AdvancedServerList/wiki
@@ -0,0 +1,34 @@
name: Feature Request
description: Suggest a new feature for the plugin
body:
- type: markdown
attributes:
value: |-
## Before opening
Please make sure you've checked the following things first:
- You're using the latest release of AdvancedServerList [[Download from Modrinth](https://modrinth.com/plugin/advancedserverlist)]
- You're using a supported Proxy/Server version. As of right now is only 1.19.x supported.
- The Feature you suggest hasn't been suggested before.
- type: dropdown
attributes:
label: Platforms
description: What platforms should this feature be usable on
multiple: true
options:
- Proxy (BungeeCord, Waterfall, ...)
- Proxy (Velocity)
- Server (Spigot, Paper, ...)
validations:
required: true
- type: textarea
attributes:
label: Feature
description: |-
Give a detailed description of what exactly should be added and/or changed in AdvancedServerList.
You can provide screenshots to further explain the idea.
When sharing code snippets, make sure to use a site such as https://paste.helpch.at to do so.
placeholder: AdvancedServerList should get ... because ...
validations:
required: true
+96
View File
@@ -0,0 +1,96 @@
# AdvancedServerList
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.
## 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">
</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>
## What is a Server List Profile?
A Server List Profile refers to a YAML file located in the plugin's `profiles` directory.
It allows you to configure specific aspects of the server display in the MC-Client's multiplayer server list, such as the MOTD, player count text, player count hover or Favicon.
> [*Read More*][profiles]
### Conditions
Thanks to conditions can you determine when a profile should be displayed in the player’s server list, to allow displaying specific text (i.e. a warning when they are using an outdated version).
When multiple profiles exist that have valid conditions will the one with the highest priority (Higher number = higher priority) be selected. Having no conditions makes the profile automatically return true.
> [*Read More*][conditions]
### Placeholders
Placeholders can be used within conditions to further customize them. They can also be used in any other text option (motd, playerCount and players) to display their respective values.
The format is `${<target> <identifier>}` which was adopted from BungeeTabListPlus. Depending on what platform you use the plugin on are only specific placeholders available.
When using the SpigotMC/PaperMC version can you also use placeholders from [PlaceholderAPI][placeholderapi] using its `%<identifier>_<values>%` placeholder format. PlaceholderAPI needs to be installed for that.
> [*Read More*][placeholders]
### Formatting
The plugin uses the MiniMessage format for a consistent, easy way of formatting your text.
Only certain options are usable for each option. As an example does motd support HEX colours and gradients, while the other options only support default colour codes.
> [*Read More*][minimessage]
## Dependencies
| Dependency | Platforms | Required? |
| ---------------- | ------------- | --------- |
| [ProtocolLib] | Spigot | Yes |
| [PlaceholderAPI] | Spigot, Paper | No |
## Statistics
This plugin sends statistics to [bStats] to display.
You can disable this in the global bStats config file located in `/plugins/bstats/`
- [BungeeCord][bstats-bungee]
- [Paper/Spigot][bstats-spigot]
- [Velocity][bstats-velocity]
## 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">
</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">
</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">
</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">
</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
[protocollib]: https://www.spigotmc.org/resources/1997/
[placeholderapi]: https://www.spigotmc.org/resources/6245/
[bstats]: https://bstats.org
[bstats-bungee]: https://bstats.org/plugin/bungeecord/AdvancedServerList/15585
[bstats-spigot]: https://bstats.org/plugin/bukkit/AdvancedServerList/15584
[bstats-velocity]: https://bstats.org/plugin/velocity/AdvancedServerList/15587
[gallery]: https://modrinth.com/mod/advancedserverlist/gallery
+14 -8
View File
@@ -7,7 +7,8 @@ name: Publish Assets
on:
release:
types: [published]
types:
- published
jobs:
buildJars:
@@ -55,15 +56,19 @@ jobs:
strategy:
matrix:
include:
- directory: bungeecord
- platforms: BungeeCord, Waterfall
directory: bungeecord
loaders: |
bungeecord
waterfall
- directory: paper
- platforms: Paper
directory: paper
loaders: paper
- directory: spigot
- platforms: Spigot
directory: spigot
loaders: spigot
- directory: velocity
- platforms: Velocity
directory: velocity
loaders: velocity
runs-on: ubuntu-latest
steps:
@@ -77,12 +82,12 @@ jobs:
id: github-release
run: |
version=$(echo ${{ github.event.release.tag_name }} | cut -d'v' -f2)
echo "::set-output name=version::$version"
echo "PLUGIN_RELEASE=$version" >> $GITHUB_OUTPUT
- name: Upload AdvancedServerList (${{ matrix.loaders }}) to GitHub and Modrinth
uses: Kir-Antipov/mc-publish@v3.2
with:
name: ${{ github.event.release.name }}
version: ${{ steps.github-release.outputs.version }}
name: ${{ github.event.release.tag_name }} (${{ matrix.platforms }})
version: ${{ steps.github-release.outputs.PLUGIN_RELEASE }}
version-type: release
files: ${{ matrix.directory}}/target/AdvancedServerList-*.jar
files-secondary: ""
@@ -92,6 +97,7 @@ jobs:
1.19
1.19.1
1.19.2
1.19.3
java: 16
modrinth-id: xss83sOY
modrinth-featured: false
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2022 Andre_601
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
+36 -22
View File
@@ -1,7 +1,27 @@
# AdvancedServerList
![platform] ![tested]
<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 made for SpigotMC, PaperMC, BungeeCord/Waterfall and Velocity. It allows you to create server list profiles to display based on priority and conditions.
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.
## 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">
</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">
</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">
</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">
</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">
</a>
## What is a Server List Profile?
A Server List Profile refers to a YAML file located in the plugin's `profiles` directory.
@@ -30,11 +50,6 @@ Only certain options are usable for each option. As an example does motd support
> [*Read More*][minimessage]
## Downloads
AdvancedServerList can be downloaded from the following places:
[![dl-modrinth]][modrinth] [![dl-spigot]][spigot] [![dl-hangar]][hangar]
## Dependencies
| Dependency | Platforms | Required? |
@@ -53,8 +68,20 @@ You can disable this in the global bStats config file located in `/plugins/bstat
## Screenshots
Please see the [Gallery Tab][gallery] for some previews.
If you have any own screenshots, feel free to share them with me. I may add them to the Gallery if they are good.
<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">
</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">
</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">
</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">
</a>
<!-- Links -->
[profiles]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles
@@ -65,8 +92,6 @@ If you have any own screenshots, feel free to share them with me. I may add them
[placeholderapi]: https://www.spigotmc.org/resources/6245/
[modrinth]: https://modrinth.com/plugin/advancedserverlist
[spigot]: https://www.spigotmc.org/resources/102910/
[hangar]: https://hangar.benndorf.dev/Andre_601/AdvancedServerList
[protocollib]: https://www.spigotmc.org/resources/1997/
[placeholderapi]: https://www.spigotmc.org/resources/6245/
@@ -77,14 +102,3 @@ If you have any own screenshots, feel free to share them with me. I may add them
[bstats-velocity]: https://bstats.org/plugin/velocity/AdvancedServerList/15587
[gallery]: https://modrinth.com/mod/advancedserverlist/gallery
<!-- Badges -->
[platform]: https://img.shields.io/badge/Platforms-Spigot%20%7C%20Paper%20%7C%20BungeeCord%20%7C%20Velocity-blue?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJ3aGl0ZSI+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTEuMDYzIDEuNDU2YTEuNzUgMS43NSAwIDAxMS44NzQgMGw4LjM4MyA1LjMxNmExLjc1IDEuNzUgMCAwMTAgMi45NTZsLTguMzgzIDUuMzE2YTEuNzUgMS43NSAwIDAxLTEuODc0IDBMMi42OCA5LjcyOGExLjc1IDEuNzUgMCAwMTAtMi45NTZsOC4zODMtNS4zMTZ6bTEuMDcxIDEuMjY3YS4yNS4yNSAwIDAwLS4yNjggMEwzLjQ4MyA4LjAzOWEuMjUuMjUgMCAwMDAgLjQyMmw4LjM4MyA1LjMxNmEuMjUuMjUgMCAwMC4yNjggMGw4LjM4My01LjMxNmEuMjUuMjUgMCAwMDAtLjQyMmwtOC4zODMtNS4zMTZ6Ij48L3BhdGg+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMS44NjcgMTIuMzI0YS43NS43NSAwIDAxMS4wMzUtLjIzMmw4Ljk2NCA1LjY4NWEuMjUuMjUgMCAwMC4yNjggMGw4Ljk2NC01LjY4NWEuNzUuNzUgMCAwMS44MDQgMS4yNjdsLTguOTY1IDUuNjg1YTEuNzUgMS43NSAwIDAxLTEuODc0IDBsLTguOTY1LTUuNjg1YS43NS43NSAwIDAxLS4yMzEtMS4wMzV6Ij48L3BhdGg+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMS44NjcgMTYuMzI0YS43NS43NSAwIDAxMS4wMzUtLjIzMmw4Ljk2NCA1LjY4NWEuMjUuMjUgMCAwMC4yNjggMGw4Ljk2NC01LjY4NWEuNzUuNzUgMCAwMS44MDQgMS4yNjdsLTguOTY1IDUuNjg1YTEuNzUgMS43NSAwIDAxLTEuODc0IDBsLTguOTY1LTUuNjg1YS43NS43NSAwIDAxLS4yMzEtMS4wMzV6Ij48L3BhdGg+PC9zdmc+
[tested]: https://img.shields.io/badge/Tested%20Versions-1.19%20%7C%201.19.1%20%7C%201.19.2-blue?style=for-the-badge&logo=image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiBmaWxsPSJ3aGl0ZSI+PHBhdGggZD0iTTE3LjI4IDkuMjhhLjc1Ljc1IDAgMDAtMS4wNi0xLjA2bC01Ljk3IDUuOTctMi40Ny0yLjQ3YS43NS43NSAwIDAwLTEuMDYgMS4wNmwzIDNhLjc1Ljc1IDAgMDAxLjA2IDBsNi41LTYuNXoiPjwvcGF0aD48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0zLjc1IDJBMS43NSAxLjc1IDAgMDAyIDMuNzV2MTYuNWMwIC45NjYuNzg0IDEuNzUgMS43NSAxLjc1aDE2LjVBMS43NSAxLjc1IDAgMDAyMiAyMC4yNVYzLjc1QTEuNzUgMS43NSAwIDAwMjAuMjUgMkgzLjc1ek0zLjUgMy43NWEuMjUuMjUgMCAwMS4yNS0uMjVoMTYuNWEuMjUuMjUgMCAwMS4yNS4yNXYxNi41YS4yNS4yNSAwIDAxLS4yNS4yNUgzLjc1YS4yNS4yNSAwIDAxLS4yNS0uMjVWMy43NXoiPjwvcGF0aD48L3N2Zz4=
[dl-modrinth]: https://img.shields.io/badge/Modrinth-30b27b?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbDpzcGFjZT0icHJlc2VydmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEuNSIgY2xpcC1ydWxlPSJldmVub2RkIiB2aWV3Qm94PSIwIDAgNjggNjgiPjxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0uMDUgMGg2NnY2NmgtNjZ6Ii8+PGNsaXBQYXRoIGlkPSJhIj48cGF0aCBkPSJNLjA1IDBoNjZ2NjZoLTY2eiIvPjwvY2xpcFBhdGg+PGcgY2xpcC1wYXRoPSJ1cmwoI2EpIj48Y2xpcFBhdGggaWQ9ImIiPjxjaXJjbGUgY3g9IjMzLjA1IiBjeT0iMzMiIHI9IjMzIi8+PC9jbGlwUGF0aD48ZyBjbGlwLXBhdGg9InVybCgjYikiPjxjbGlwUGF0aCBpZD0iYyI+PHBhdGggZD0iTTgzLjA1LTE3aC0xMDBWODNoMTAwVi0xN1pNMjkuMDUxIDMyLjI5NWwuMDc3IDEuNzU3IDguODI5IDMyLjk2MyA3Ljg0NC0yLjEwMi04LjU5Ny0zMi4wOTRMNDMuMDA5LS4xMTNsLTcuOTk3LTEuNDEtNS45NjEgMzMuODE4WiIvPjwvY2xpcFBhdGg+PGcgY2xpcC1wYXRoPSJ1cmwoI2MpIj48cGF0aCBmaWxsPSIjRkZGIiBkPSJNMzMuMDUgMGMxOC4yMDYgMCAzMi45ODggMTQuNzg3IDMyLjk4OCAzM1M1MS4yNTYgNjYgMzMuMDUgNjZDMTQuODQzIDY2IC4wNjEgNTEuMjEzLjA2MSAzM1MxNC44NDMgMCAzMy4wNSAwWm0wIDljMTMuMjQgMCAyMy45ODggMTAuNzU1IDIzLjk4OCAyNFM0Ni4yOSA1NyAzMy4wNSA1N0MxOS44MDkgNTcgOS4wNjEgNDYuMjQ1IDkuMDYxIDMzUzE5LjgwOSA5IDMzLjA1IDlaIi8+PC9nPjxjbGlwUGF0aCBpZD0iZCI+PHBhdGggZD0iTS0xNi45NS0xN3Y0Nmg1MGwxLjM2OC4yNDFMODIuMDUgNDYuNTc4bC0yLjczNyA3LjUxN0wzMi4zNDQgMzdILTE2Ljk1djQ2aDEwMFYtMTdoLTEwMFoiLz48L2NsaXBQYXRoPjxnIGNsaXAtcGF0aD0idXJsKCNkKSI+PHBhdGggZmlsbD0iI0ZGRiIgZD0iTTMzLjA1LTE3YzI3LjU5NSAwIDUwIDIyLjQwNCA1MCA1MHMtMjIuNDA1IDUwLTUwIDUwYy0yNy41OTYgMC01MC0yMi40MDQtNTAtNTBzMjIuNDA0LTUwIDUwLTUwWm0wIDljMjIuNjI4IDAgNDEgMTguMzcxIDQxIDQxcy0xOC4zNzIgNDEtNDEgNDFjLTIyLjYyOSAwLTQxLTE4LjM3MS00MS00MXMxOC4zNzEtNDEgNDEtNDFaIi8+PC9nPjxjbGlwUGF0aCBpZD0iZSI+PHBhdGggZD0iTTMzLjA1LTE3YzI3LjU5NSAwIDUwIDIyLjQwNCA1MCA1MHMtMjIuNDA1IDUwLTUwIDUwYy0yNy41OTYgMC01MC0yMi40MDQtNTAtNTBzMjIuNDA0LTUwIDUwLTUwWm0wIDM5LjU0OWM1Ljc2NyAwIDEwLjQ1IDQuNjgzIDEwLjQ1IDEwLjQ1MSAwIDUuNzY4LTQuNjgzIDEwLjQ1MS0xMC40NSAxMC40NTEtNS43NjggMC0xMC40NTEtNC42ODMtMTAuNDUxLTEwLjQ1MSAwLTUuNzY4IDQuNjgzLTEwLjQ1MSAxMC40NTEtMTAuNDUxWiIvPjwvY2xpcFBhdGg+PGcgY2xpcC1wYXRoPSJ1cmwoI2UpIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiNGRkYiIHN0cm9rZS13aWR0aD0iOSIgZD0ibTMzLjA1IDMzLTQ0LjgyOSAyNS44ODIiLz48L2c+PGNsaXBQYXRoIGlkPSJmIj48cGF0aCBkPSJNMzMuMDUtMTdjMjcuNTk1IDAgNTAgMjIuNDA0IDUwIDUwcy0yMi40MDUgNTAtNTAgNTBjLTI3LjU5NiAwLTUwLTIyLjQwNC01MC01MHMyMi40MDQtNTAgNTAtNTBabTAgMjUuMzZjMTMuNTk5IDAgMjQuNjQgMTEuMDQxIDI0LjY0IDI0LjY0UzQ2LjY0OSA1Ny42NCAzMy4wNSA1Ny42NEMxOS40NSA1Ny42NCA4LjQwOSA0Ni41OTkgOC40MDkgMzNTMTkuNDUgOC4zNiAzMy4wNSA4LjM2WiIvPjwvY2xpcFBhdGg+PGcgY2xpcC1wYXRoPSJ1cmwoI2YpIj48cGF0aCBmaWxsPSJub25lIiBzdHJva2U9IiNGRkYiIHN0cm9rZS13aWR0aD0iOSIgZD0ibTMzLjA1IDMzIDUwLTEzLjM5NyIvPjwvZz48cGF0aCBmaWxsPSIjRkZGIiBkPSJNMjAuMjkzIDM1Ljc0NiAxOC4wNSAyOGw4LTkgMTEtMyA0IDQtNiA2LTQgMS0zIDQgMS4xMiA0LjI0IDMuMTEyIDMuMDkgNC45NjQtLjU5OCAyLjg2Ni0yLjk2NCA4LjE5Ni0yLjE5NiAxLjQ2NCA1LjQ2NC04LjA5OCA4LjAyNkwyOS44OCA0OC40OWwtNS41ODctNS44MTUtNC02LjkyOVoiLz48L2c+PC9nPjwvc3ZnPg==
[dl-spigot]: https://img.shields.io/badge/Spigot-ed8106?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBmaWxsPSIjRkZGIj48cGF0aCBkPSJNNDE2IDQ4MGMwIDE3LjYyIDE0LjM4IDMyIDMyIDMyczMyLTE0LjM4IDMyLTMycy0zMi02NC0zMi02NFM0MTYgNDYyLjQgNDE2IDQ4MHpNMzUyIDE5MmgtMzguNTRDMjk3LjcgMTc4LjUgMjc3LjkgMTY4LjkgMjU2IDE2NFYxMTYuNUwyMjQgMTEzTDE5MiAxMTYuNVYxNjRDMTcwLjEgMTY5IDE1MC4zIDE3OC42IDEzNC41IDE5MkgxNkM3LjEyNSAxOTIgMCAxOTkuMSAwIDIwOHY5NkMwIDMxMi45IDcuMTI1IDMyMCAxNiAzMjBoOTIuNzhDMTI5LjQgMzU3LjggMTczIDM4NCAyMjQgMzg0czk0LjU5LTI2LjI1IDExNS4yLTY0SDM1MmMxNy42MiAwIDMyIDE0LjI5IDMyIDMxLjkxUzM5OC40IDM4NCA0MTYgMzg0aDY0YzE3LjYyIDAgMzItMTQuMzggMzItMzJDNTEyIDI2My42IDQ0MC40IDE5MiAzNTIgMTkyek04MS42MyA5NS44OEwyMjQgODAuODhsMTQyLjQgMTVDMzc1LjkgOTYuODggMzg0IDg5LjEyIDM4NCA3OS4xMlY0OC44OWMwLTEwLTguMTI1LTE3Ljc0LTE3LjYyLTE2Ljc0TDI1NiA0My43NVYxNkMyNTYgNy4xMjUgMjQ4LjkgMCAyNDAgMGgtMzJDMTk5LjEgMCAxOTIgNy4xMjUgMTkyIDE2djI3Ljc1TDgxLjYzIDMyLjE0QzcyLjEzIDMxLjE0IDY0IDM4Ljg5IDY0IDQ4Ljg5Vjc5LjEyQzY0IDg5LjEyIDcyLjEzIDk2Ljg4IDgxLjYzIDk1Ljg4eiIvPjwvc3ZnPg==
[dl-hangar]: https://img.shields.io/badge/Hangar%20(Beta)-444?style=for-the-badge&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNDEgMjI0LjUiPjxkZWZzPjxzdHlsZT4uYXtmaWxsOm5vbmU7fS5iLC5se2ZpbGw6I2ZmZjt9LmIsLmMsLmQsLmUsLmYsLmcsLmgsLmksLmp7ZmlsbC1ydWxlOmV2ZW5vZGQ7fS5je2ZpbGw6I2ZhMDt9LmR7ZmlsbDojYWFhO30uZXtmaWxsOiM1NWY7fS5me2ZpbGw6IzVmNTt9Lmd7ZmlsbDojNjdjYmRmO30uaHtmaWxsOiNmNTU7fS5pe2ZpbGw6I2Y1Zjt9Lmp7ZmlsbDojZmY1O30ua3tmaWxsOiM0NDQ7fTwvc3R5bGU+PC9kZWZzPjxyZWN0IGNsYXNzPSJhIiB4PSIyMS4yIiB5PSIxMy42IiB3aWR0aD0iMjE0LjciIGhlaWdodD0iMTk5Ljk0Ii8+PHBhdGggY2xhc3M9ImIiIGQ9Ik01NTAuOCwzOTkuNSwzOTEuMiw0NzUuMyw0NzIuNSw2MjRsMTU5LjYtNzUuOEw1NTAuOCwzOTkuNVoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zOTEuMiAtMzk5LjUpIi8+PHBhdGggY2xhc3M9ImMiIGQ9Ik01NTcsNDAxLjYsMzkzLjQsNDY5LjVsNzIuOCwxNTIuNEw2MjkuOSw1NTRaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzkxLjIgLTM5OS41KSIvPjxwYXRoIGNsYXNzPSJkIiBkPSJNNTYzLjIsNDA0LDM5NS45LDQ2My44bDY0LjIsMTU1LjgsMTY3LjMtNTkuOFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zOTEuMiAtMzk5LjUpIi8+PHBhdGggY2xhc3M9ImUiIGQ9Ik01NjkuMiw0MDYuNiwzOTguOCw0NTguMmw1NS4zLDE1OC43LDE3MC40LTUxLjZMNTY5LjIsNDA2LjZaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzkxLjIgLTM5OS41KSIvPjxwYXRoIGNsYXNzPSJmIiBkPSJNNTc1LDQwOS42LDQwMiw0NTIuOGw0Ni4zLDE2MS4xLDE3My4xLTQzLjFaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMzkxLjIgLTM5OS41KSIvPjxwYXRoIGNsYXNzPSJnIiBkPSJNNTgxLjEsNDEyLjVsLTE3NS41LDM1TDQ0My4yLDYxMWwxNzUuNS0zNUw1ODEuMSw0MTIuNVoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zOTEuMiAtMzk5LjUpIi8+PHBhdGggY2xhc3M9ImgiIGQ9Ik01ODYuMSw0MTYuMyw0MDkuMiw0NDIuNGwyOCwxNjQuOCwxNzYuOS0yNi4xLTI4LTE2NC44WiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTM5MS4yIC0zOTkuNSkiLz48cGF0aCBjbGFzcz0iaSIgZD0iTTU5MS40LDQyMC4xLDQxMy4yLDQzNy41bDE4LjcsMTY2TDYxMC4xLDU4Niw1OTEuNCw0MjAuMVoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zOTEuMiAtMzk5LjUpIi8+PHBhdGggY2xhc3M9ImoiIGQ9Ik01OTYuNCw0MjQuMWwtMTc4LjksOC43LDkuNCwxNjYuNiwxNzguOS04LjctOS40LTE2Ni42WiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTM5MS4yIC0zOTkuNSkiLz48cmVjdCBjbGFzcz0iayIgeD0iMzAuOSIgeT0iMjguOCIgd2lkdGg9IjE3OS4yIiBoZWlnaHQ9IjE2Ni44OCIvPjxwYXRoIGNsYXNzPSJsIiBkPSJNNTU0LjcsNTAyLjdjLTkuNy0zLjYtMjQsMTAuMi0zMSwzMS40YTgzLjksODMuOSwwLDAsMC0zLjUsMzUuOWwtNC41LTEuOWMtOC42LTI2LjctMy44LTU1LjksMTEuMS03N1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zOTEuMiAtMzk5LjUpIi8+PHBhdGggY2xhc3M9ImwiIGQ9Ik01NjEsNTQ4LjNsLTMzLjItMTMuN2M2LjEtMTguNSwxNy40LTI5LjYsMjQuNy0yOS42YTcuOCw3LjgsMCwwLDEsMi4yLjRsLjYuM2MyLjYsMS4yLDEwLjUsOCw1LjcsNDIuNiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTM5MS4yIC0zOTkuNSkiLz48cGF0aCBjbGFzcz0ibCIgZD0iTTU0OS4xLDQ2Ni4yYTczLjQsNzMuNCwwLDAsMC0yNS44LDIzLjRjLTE0LjYsMjEuMi0xOS42LDQ5LjktMTIsNzYuN2E4Mi4yLDgyLjIsMCwwLDAsMy4zLDkuNWwtNDQuNS0xOC40Yy0xNi44LTQxLjItMS40LTkwLjMsMzQuNS0xMDkuN1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zOTEuMiAtMzk5LjUpIi8+PC9zdmc+Cg==
+6 -2
View File
@@ -2,7 +2,7 @@
<!--
~ MIT License
~
~ Copyright (c) 2022 Andre_601
~ 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
@@ -103,7 +103,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
@@ -123,6 +123,10 @@
<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>
</relocation>
</relocations>
<filters>
<filter>
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -30,8 +30,8 @@ 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.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.core.ProxyCore;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.interfaces.core.ProxyCore;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
@@ -83,6 +83,9 @@ public class BungeeCordCore extends Plugin implements ProxyCore<Favicon, ServerP
@Override
public void clearFaviconCache(){
if(faviconHandler == null)
return;
faviconHandler.clearCache();
}
@@ -119,6 +122,11 @@ public class BungeeCordCore extends Plugin implements ProxyCore<Favicon, ServerP
return getProxy().getVersion();
}
@Override
public String getLoader(){
return "bungeecord";
}
@Override
public List<ServerPing.PlayerInfo> createPlayers(List<String> lines, Placeholders... placeholders){
List<ServerPing.PlayerInfo> players = new ArrayList<>(lines.size());
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -25,13 +25,15 @@
package ch.andre601.advancedserverlist.bungeecord;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class BungeePlayer extends GenericPlayer<ProxiedPlayer>{
public BungeePlayer(String name, int protocol){
this.name = name;
public BungeePlayer(CachedPlayer player, int protocol){
this.name = player.getName();
this.protocol = protocol;
this.uuid = player.getUuid();
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -0,0 +1,157 @@
/*
* 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.bungeecord.BungeeCordCore;
import ch.andre601.advancedserverlist.bungeecord.BungeePlayer;
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.api.Favicon;
import net.md_5.bungee.api.ServerPing;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.ProxyPingEvent;
import java.awt.image.BufferedImage;
import java.net.InetSocketAddress;
import java.util.List;
public class BungeeEventWrapper implements GenericEventWrapper<ProxiedPlayer, Favicon>{
private final BungeeCordCore plugin;
private final ProxyPingEvent event;
private final ServerPing.Protocol protocol;
private final ServerPing ping;
public BungeeEventWrapper(BungeeCordCore plugin, ProxyPingEvent event){
this.plugin = plugin;
this.event = event;
this.protocol = event.getResponse().getVersion();
this.ping = event.getResponse();
}
@Override
public void setMaxPlayers(int maxPlayers){
ping.getPlayers().setMax(maxPlayers);
}
@Override
public void setMotd(Component component){
ping.setDescriptionComponent(new TextComponent(BungeeComponentSerializer.get().serialize(component)));
}
@Override
public void hidePlayers(){
ping.setPlayers(null);
}
@Override
public void setPlayerCount(String name){
protocol.setName(name);
protocol.setProtocol(-1);
}
@Override
public void setPlayers(List<String> players, GenericPlayer<ProxiedPlayer> player, PlayerPlaceholders playerPlaceholders, ServerPlaceholders serverPlaceholders){
ServerPing.PlayerInfo[] playerInfos = plugin.createPlayers(players, playerPlaceholders, serverPlaceholders)
.toArray(new ServerPing.PlayerInfo[0]);
if(playerInfos.length > 0)
ping.getPlayers().setSample(playerInfos);
}
@Override
public void setFavicon(Favicon favicon){
ping.setFavicon(favicon);
}
@Override
public void setDefaultFavicon(){
ping.setFavicon(ping.getFaviconObject());
}
@Override
public void updateEvent(){
this.ping.setVersion(this.protocol);
this.event.setResponse(this.ping);
}
@Override
public boolean isInvalidProtocol(){
return protocol == null;
}
@Override
public int getProtocolVersion(){
return this.protocol.getProtocol();
}
@Override
public int getOnlinePlayers(){
return ping.getPlayers().getOnline();
}
@Override
public int getMaxPlayers(){
return ping.getPlayers().getMax();
}
@Override
public String getPlayerIP(){
return ((InetSocketAddress)event.getConnection().getSocketAddress()).getHostString();
}
@Override
public String parsePAPIPlaceholders(String text, GenericPlayer<ProxiedPlayer> player){
return text;
}
@Override
public String getVirtualHost(){
return this.resolveHost(event.getConnection().getVirtualHost());
}
@Override
public PluginCore<Favicon> getPlugin(){
return plugin;
}
@Override
public GenericPlayer<ProxiedPlayer> createPlayer(CachedPlayer player, int protocol){
return new BungeePlayer(player, protocol);
}
@Override
public Favicon createFavicon(BufferedImage image) throws IllegalArgumentException{
return Favicon.create(image);
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -26,6 +26,7 @@
package ch.andre601.advancedserverlist.bungeecord.events;
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.PostLoginEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler;
@@ -44,6 +45,8 @@ public class JoinEvent implements Listener{
@EventHandler
public void onJoin(PostLoginEvent event){
InetSocketAddress address = (InetSocketAddress)event.getPlayer().getPendingConnection().getSocketAddress();
plugin.getCore().getPlayerHandler().addPlayer(event.getPlayer().getName(), address.getHostString());
ProxiedPlayer player = event.getPlayer();
plugin.getCore().getPlayerHandler().addPlayer(address.getHostString(), player.getName(), player.getUniqueId());
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -26,24 +26,12 @@
package ch.andre601.advancedserverlist.bungeecord.events;
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
import ch.andre601.advancedserverlist.bungeecord.BungeePlayer;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.ProfileManager;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.api.Favicon;
import net.md_5.bungee.api.ServerPing;
import net.md_5.bungee.api.chat.TextComponent;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import net.md_5.bungee.api.event.ProxyPingEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler;
import net.md_5.bungee.event.EventPriority;
import java.net.InetSocketAddress;
public class PingEvent implements Listener{
private final BungeeCordCore plugin;
@@ -55,91 +43,6 @@ public class PingEvent implements Listener{
@EventHandler(priority = EventPriority.LOW)
public void onProxyPing(ProxyPingEvent event){
ServerPing ping = event.getResponse();
ServerPing.Protocol protocol = ping.getVersion();
if(protocol == null)
return;
String playerName = plugin.getCore().getPlayerHandler().getPlayerByIp(
((InetSocketAddress)event.getConnection().getSocketAddress()).getHostString()
);
InetSocketAddress host = event.getConnection().getVirtualHost();
int online = ping.getPlayers().getOnline();
int max = ping.getPlayers().getMax();
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(new BungeePlayer(playerName, protocol.getProtocol()));
ServerPlaceholders serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
ServerListProfile profile = ProfileManager.get(plugin.getCore())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.getProfile();
if(profile == null)
return;
if(profile.isExtraPlayersEnabled()){
max = online + profile.getExtraPlayers();
ping.getPlayers().setMax(max);
}
serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
if(!profile.getMotd().isEmpty()){
TextComponent component = new TextComponent(BungeeComponentSerializer.get().serialize(
ComponentParser.list(profile.getMotd())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.toComponent()
));
ping.setDescriptionComponent(component);
}
if(profile.shouldHidePlayers()){
ping.setPlayers(null);
}
if(!profile.getPlayerCount().isEmpty() && !profile.shouldHidePlayers()){
protocol.setName(ComponentParser.text(profile.getPlayerCount())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.toString()
);
protocol.setProtocol(-1);
}
if(!profile.getPlayers().isEmpty() && !profile.shouldHidePlayers()){
ServerPing.PlayerInfo[] playerInfos = plugin.createPlayers(profile.getPlayers(), playerPlaceholders, serverPlaceholders)
.toArray(new ServerPing.PlayerInfo[0]);
if(playerInfos.length > 0)
ping.getPlayers().setSample(playerInfos);
}
if(!profile.getFavicon().isEmpty()){
String favName = StringReplacer.replace(profile.getFavicon(), playerPlaceholders.getReplacements());
Favicon favicon = plugin.getFaviconHandler().getFavicon(favName, image -> {
try{
return Favicon.create(image);
}catch(Exception ex){
plugin.getPluginLogger().warn("Unable to create Favicon. %s", ex.getMessage());
return null;
}
});
if(favicon == null){
plugin.getPluginLogger().warn("Could not obtain valid Favicon to use.");
ping.setFavicon(ping.getFaviconObject());
}else{
ping.setFavicon(favicon);
}
}
ping.setVersion(protocol);
event.setResponse(ping);
PingEventHandler.handleEvent(new BungeeEventWrapper(plugin, event));
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -52,4 +52,9 @@ public class BungeeLogger implements PluginLogger{
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);
}
}
+42 -6
View File
@@ -2,7 +2,7 @@
<!--
~ MIT License
~
~ Copyright (c) 2022 Andre_601
~ 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
@@ -43,6 +43,13 @@
<maven.compiler.target>16</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>flexver-repo</id>
<url>https://repo.sleeping.town/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spongepowered</groupId>
@@ -52,24 +59,47 @@
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.11.0</version>
<version>4.12.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.11.0</version>
<version>4.12.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-legacy</artifactId>
<version>4.11.0</version>
<version>4.12.0</version>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.1</version>
<version>3.1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
</dependency>
<dependency>
<groupId>com.unascribed</groupId>
<artifactId>flexver-java</artifactId>
<version>1.0.2</version>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
@@ -89,7 +119,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
@@ -101,6 +131,12 @@
</excludes>
</filter>
</filters>
<relocations>
<relocation>
<pattern>com.unascribed</pattern>
<shadedPattern>ch.andre601.advancedserverlist.core.depends.flexver</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
<execution>
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -25,6 +25,7 @@
package ch.andre601.advancedserverlist.core;
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;
@@ -33,7 +34,7 @@ import ch.andre601.advancedserverlist.core.profiles.players.PlayerHandler;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.*;
import java.util.Properties;
public class AdvancedServerList{
@@ -42,6 +43,8 @@ public class AdvancedServerList{
private final CommandHandler commandHandler;
private final PlayerHandler playerHandler;
private UpdateChecker updateChecker;
private String version;
public AdvancedServerList(PluginCore<?> plugin){
@@ -74,8 +77,14 @@ public class AdvancedServerList{
}
public void disable(){
getPlugin().getPluginLogger().info("Saving cache.data file...");
getPlugin().getPluginLogger().info("Saving playercache.json file...");
getPlayerHandler().save();
if(updateChecker != null){
getPlugin().getPluginLogger().info("Disabling Update Checker...");
updateChecker.disable();
}
getPlugin().getPluginLogger().info("AdvancedServerList disabled!");
}
@@ -88,7 +97,6 @@ public class AdvancedServerList{
resolveVersion();
getPlugin().getPluginLogger().info("Starting AdvancedServerList v%s...", version);
getPlugin().getPluginLogger().info("Platform: " + plugin.getPlatformName() + " " + plugin.getPlatformVersion());
if(getFileHandler().loadConfig()){
@@ -117,7 +125,7 @@ public class AdvancedServerList{
plugin.loadEvents();
getPlugin().getPluginLogger().info("Events loaded!");
getPlugin().getPluginLogger().info("Loading cache.data...");
getPlugin().getPluginLogger().info("Loading playercache.json...");
getPlayerHandler().load();
getPlugin().getPluginLogger().info("Loading bStats metrics. Disable it in the global config under /plugins/bstats/");
@@ -125,6 +133,9 @@ public class AdvancedServerList{
getPlugin().getPluginLogger().info("Metrics loaded!");
getPlugin().getPluginLogger().info("AdvancedServerList is ready!");
if(getFileHandler().getBoolean("check_updates"))
this.updateChecker = new UpdateChecker(this);
}
private void printBanner(){
@@ -0,0 +1,37 @@
/*
* 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.check;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.ThreadFactory;
public class UpdateCheckThread implements ThreadFactory{
@Override
public Thread newThread(@NotNull Runnable r){
return new Thread(r, "AdvancedServerList Update-Thread");
}
}
@@ -0,0 +1,223 @@
/*
* 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.check;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import com.unascribed.flexver.FlexVerComparator;
import io.leangen.geantyref.TypeToken;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class UpdateChecker{
private final String url = "https://api.modrinth.com/v2/project/advancedserverlist/version?loaders=[\"%s\"]";
private final OkHttpClient client = new OkHttpClient();
private final AdvancedServerList core;
private final PluginLogger logger;
private final String loader;
private final Type listType = new TypeToken<ArrayList<ModrinthVersion>>(){}.getType();
private final Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.setPrettyPrinting()
.setLenient()
.create();
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new UpdateCheckThread());
public UpdateChecker(AdvancedServerList core){
this.core = core;
this.logger = core.getPlugin().getPluginLogger();
this.loader = core.getPlugin().getLoader();
startUpdateChecker();
}
public void startUpdateChecker(){
executor.scheduleAtFixedRate(() -> {
logger.info("Checking for a new update...");
checkUpdate().whenComplete((version, throwable) -> {
if(version == null || throwable != null){
logger.warn("Failed to look for any updates. See previous messages for reasons.");
return;
}
int result = version.compare(core.getVersion());
switch(result){
case -1 -> printUpdateBanner(version.getVersionNumber(), version.getId(), version.isRelease());
case 0 -> logger.info("No new update found. You're running the latest version!");
case 1 -> logger.info(
"Your version (%s) is higher than the latest release (%s). Are you running a dev build?",
core.getVersion(), version.getVersionNumber()
);
}
});
}, 0L, 12L, TimeUnit.HOURS);
}
public void disable(){
executor.shutdown();
client.dispatcher().executorService().shutdown();
try{
if(!executor.awaitTermination(1, TimeUnit.SECONDS)){
executor.shutdownNow();
if(!executor.awaitTermination(1, TimeUnit.SECONDS))
logger.warn("Scheduler didn't terminate in time!");
}
if(!client.dispatcher().executorService().awaitTermination(1, TimeUnit.SECONDS)){
client.dispatcher().executorService().shutdownNow();
if(!client.dispatcher().executorService().awaitTermination(1, TimeUnit.SECONDS))
logger.warn("OkHttp's Scheduler didn't terminate in time!");
}
}catch(InterruptedException ex){
executor.shutdownNow();
Thread.currentThread().interrupt();
}
}
private CompletableFuture<ModrinthVersion> checkUpdate(){
return CompletableFuture.supplyAsync(() -> {
PluginLogger logger = core.getPlugin().getPluginLogger();
if(core.getVersion().equals("UNKNOWN")){
logger.warn("Cannot perform Update check! Plugin version couldn't be parsed.");
return null;
}
Request request = new Request.Builder()
.url(String.format(url, loader))
.header("User-Agent", "AdvancedServerList-" + loader + "/" + core.getVersion())
.build();
try(Response response = client.newCall(request).execute()){
if(!response.isSuccessful()){
logger.warn("Encountered a non-successful response from Modrinth! Code: %d", response.code());
return null;
}
ResponseBody body = response.body();
if(body == null){
logger.warn("Received an empty Response body from Modrinth!");
return null;
}
String responseString = body.string();
if(responseString.isEmpty()){
logger.warn("Received an empty Response body from Modrinth!");
return null;
}
List<ModrinthVersion> list = gson.fromJson(responseString, listType);
if(list == null || list.isEmpty()){
logger.warn("Couldn't convert JSON Array into a valid list.");
return null;
}
ModrinthVersion version = list.get(0);
if(version.getVersionNumber() == null || version.getVersionNumber().isEmpty()){
logger.warn("Cannot check latest version. Received version number was null/empty.");
return null;
}
return version;
}catch(JsonSyntaxException ex){
logger.warn("Encountered invalid JSON from Response body!", ex);
return null;
}catch(IOException ex){
logger.warn("Encountered Exception while checking for an update!", ex);
return null;
}
});
}
private void printUpdateBanner(String version, String versionId, boolean isRelease){
logger.info("==================================================================");
logger.info("You are running an outdated version of AdvancedServerList!");
logger.info("");
logger.info("Your version: %s", core.getVersion());
logger.info("Modrinth version: %s", version);
logger.info("");
if(!isRelease){
logger.info("WARNING: This release is an Alpha/Beta! It may contain");
logger.info(" breaking changes!");
logger.info("");
}
logger.info("You can download the latest release from here:");
logger.info("https://modrinth.com/plugin/advancedserverlist/version/%s", versionId);
logger.info("==================================================================");
}
public static class ModrinthVersion{
@SuppressWarnings("FieldMayBeFinal")
private String id;
@SuppressWarnings("FieldMayBeFinal")
private String versionNumber;
@SuppressWarnings("FieldMayBeFinal")
private String versionType;
public ModrinthVersion(String id, String versionNumber, String versionType){
this.id = id;
this.versionNumber = versionNumber;
this.versionType = versionType;
}
public String getId(){
return id;
}
public String getVersionNumber(){
return versionNumber;
}
public boolean isRelease(){
return versionType.equals("release");
}
public int compare(String version){
return FlexVerComparator.compare(version, versionNumber);
}
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -62,7 +62,7 @@ public class CommandHandler{
}
if(core.getFileHandler().reloadProfiles()){
sender.sendMsg("%s <green>Loaded <grey>%s Profile(s)</grey>!", prefix, core.getFileHandler().getProfiles());
sender.sendMsg("%s <green>Loaded <grey>%d Profile(s)</grey>!", prefix, core.getFileHandler().getProfiles().size());
}else{
sender.sendMsg("%s <red>Cannot load Profiles!", errorPrefix);
}
@@ -0,0 +1,127 @@
/*
* 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.events;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileEntry;
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileManager;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
public class PingEventHandler{
public static <P, F> void handleEvent(GenericEventWrapper<P, F> event){
if(event.isInvalidProtocol())
return;
PluginCore<F> plugin = event.getPlugin();
GenericPlayer<P> player = event.createPlayer(
plugin.getCore().getPlayerHandler().getCachedPlayer(event.getPlayerIP()),
event.getProtocolVersion()
);
String host = event.getVirtualHost();
int online = event.getOnlinePlayers();
int max = event.getMaxPlayers();
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(player);
ServerPlaceholders serverPlaceholders = new ServerPlaceholders(online, max, host);
ServerListProfile profile = ProfileManager.get(plugin.getCore())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.getProfile();
if(profile == null)
return;
ProfileEntry entry = ProfileManager.merge(profile);
if(entry.isExtraPlayersEnabled().getValue(false)){
max = online + (entry.getExtraPlayersCount() == null ? 0 : entry.getExtraPlayersCount());
event.setMaxPlayers(max);
}
serverPlaceholders = new ServerPlaceholders(online, max, host);
if(!entry.getMOTD().isEmpty()){
event.setMotd(
ComponentParser.list(entry.getMOTD())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.modifyText(text -> event.parsePAPIPlaceholders(text, player))
.toComponent()
);
}
boolean hidePlayers = entry.isHidePlayersEnabled().getValue(false);
if(hidePlayers){
event.hidePlayers();
}
if(!entry.getPlayerCountText().isEmpty() && !hidePlayers){
event.setPlayerCount(
ComponentParser.text(entry.getPlayerCountText())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.modifyText(text -> event.parsePAPIPlaceholders(text, player))
.toString()
);
}
if(!entry.getPlayers().isEmpty() && !hidePlayers){
event.setPlayers(entry.getPlayers(), player, playerPlaceholders, serverPlaceholders);
}
if(!entry.getFavicon().isEmpty()){
String favicon = StringReplacer.replace(entry.getFavicon(), playerPlaceholders.getReplacements());
F fav = plugin.getFaviconHandler().getFavicon(favicon, image -> {
try{
return event.createFavicon(image);
}catch(Exception ex){
plugin.getPluginLogger().warn("Encountered an Exception while creating Favicon!", ex);
return null;
}
});
if(fav == null){
event.setDefaultFavicon();
}else{
event.setFavicon(fav);
}
}
event.updateEvent();
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -27,7 +27,9 @@ 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.profile.ProfileEntry;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileSerializer;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
@@ -106,6 +108,7 @@ public class FileHandler{
return false;
}
}
return reloadProfiles();
}
@@ -127,7 +130,7 @@ public class FileHandler{
if(tmp == null)
continue;
profiles.add(new ServerListProfile(tmp, logger));
profiles.add(ServerListProfile.Builder.resolve(file.getName(), tmp, logger).build());
logger.info("Loaded " + file.getName());
}
@@ -142,6 +145,7 @@ public class FileHandler{
public ConfigurationNode getConfigurationNode(Path path){
YamlConfigurationLoader loader = YamlConfigurationLoader.builder()
.defaultOptions(opts -> opts.serializers(build -> build.register(ProfileEntry.class, ProfileSerializer.INSTANCE)))
.path(path)
.build();
@@ -156,4 +160,8 @@ public class FileHandler{
public String getString(String def, Object... path){
return node.node(path).getString(def);
}
public boolean getBoolean(Object... path){
return node.node(path).getBoolean();
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -32,4 +32,6 @@ public interface PluginLogger{
void warn(String msg, Object... args);
void warn(String msg, Throwable throwable);
void warn(String msg, Throwable throwable, Object... args);
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -52,4 +52,6 @@ public interface PluginCore<F>{
String getPlatformName();
String getPlatformVersion();
String getLoader();
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -0,0 +1,80 @@
/*
* 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.events;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
import net.kyori.adventure.text.Component;
import java.awt.image.BufferedImage;
import java.net.InetSocketAddress;
import java.util.List;
public interface GenericEventWrapper<P, F>{
void setMaxPlayers(int maxPlayers);
void setMotd(Component component);
void hidePlayers();
void setPlayerCount(String name);
void setPlayers(List<String> players, GenericPlayer<P> player, PlayerPlaceholders playerPlaceholders, ServerPlaceholders serverPlaceholders);
void setFavicon(F favicon);
void setDefaultFavicon();
void updateEvent();
boolean isInvalidProtocol();
int getProtocolVersion();
int getOnlinePlayers();
int getMaxPlayers();
String getPlayerIP();
String parsePAPIPlaceholders(String text, GenericPlayer<P> player);
String getVirtualHost();
PluginCore<F> getPlugin();
GenericPlayer<P> createPlayer(CachedPlayer player, int protocol);
F createFavicon(BufferedImage image) throws Exception;
default String resolveHost(InetSocketAddress address){
return address == null ? null : address.getHostString();
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -23,27 +23,32 @@
*
*/
package ch.andre601.advancedserverlist.core.profiles.replacer;
package ch.andre601.advancedserverlist.core.objects;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Map;
import java.util.UUID;
/*
* Original by Imo van den Berge (aka Bergerkiller: https://github.com/Bergerkiller)
*
* Original Source: https://github.com/bergerhealer/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/collections/EntryList.java
*/
public class EntryList<K, V> extends ArrayList<Map.Entry<K, V>>{
public void add(K key, V value){
add(new AbstractMap.SimpleEntry<>(key, value));
@SuppressWarnings("FieldMayBeFinal")
public class CachedPlayer{
private String ip;
private String name;
private UUID uuid;
public CachedPlayer(String ip, String name, UUID uuid){
this.ip = ip;
this.name = name;
this.uuid = uuid;
}
public boolean containsKey(K key){
for(Map.Entry<K, V> entry : this){
if(entry.getKey().equals(key))
return true;
}
return false;
public String getIp(){
return ip;
}
public String getName(){
return name;
}
public UUID getUuid(){
return uuid;
}
}
@@ -0,0 +1,53 @@
/*
* 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.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{
public static final NullBool FALSE = new NullBool(false);
public static final NullBool NULL = new NullBool(null);
private final Boolean value;
public NullBool(Boolean value){
this.value = value;
}
public boolean isNull(){
return value == null;
}
public boolean getValue(boolean def){
return isNull() ? def : value;
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,64 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022 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;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
import java.util.HashMap;
import java.util.Map;
public class ProfileManager{
private final AdvancedServerList core;
private final Map<String, Object> replacements = new HashMap<>();
private ProfileManager(AdvancedServerList core){
this.core = core;
}
public static ProfileManager get(AdvancedServerList core){
return new ProfileManager(core);
}
public ProfileManager replacements(Placeholders placeholders){
this.replacements.putAll(placeholders.getReplacements());
return this;
}
public ServerListProfile getProfile(){
for(ServerListProfile profile : core.getFileHandler().getProfiles()){
if(profile.getMotd().isEmpty() && profile.getPlayers().isEmpty() && profile.getPlayerCount().isEmpty())
continue;
if(profile.evalConditions(replacements))
return profile;
}
return null;
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -27,118 +27,162 @@ package ch.andre601.advancedserverlist.core.profiles;
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;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random;
public class ServerListProfile{
private final int priority;
private final List<Expression> expressions;
private final ProfileEntry defaultProfile;
private final List<String> motd;
private final List<String> players;
private final String playerCount;
private final String favicon;
private final boolean hidePlayers;
private final boolean extraPlayersEnabled;
private final int extraPlayers;
private final List<ProfileEntry> profiles;
public ServerListProfile(ConfigurationNode node, PluginLogger logger){
this.priority = node.node("priority").getInt();
this.expressions = createExpressions(getList(node, false, "conditions"), logger);
this.motd = getList(node, true, "motd");
this.players = getList(node, false, "playerCount", "hover");
this.playerCount = node.node("playerCount", "text").getString("");
this.favicon = node.node("favicon").getString("");
this.hidePlayers = node.node("playerCount", "hidePlayers").getBoolean();
this.extraPlayersEnabled = node.node("playerCount", "extraPlayers", "enabled").getBoolean();
this.extraPlayers = node.node("playerCount", "extraPlayers", "amount").getInt();
private final Random random = new Random();
public ServerListProfile(int priority, List<Expression> expressions, List<ProfileEntry> profiles, ProfileEntry defaultProfile){
this.priority = priority;
this.expressions = expressions;
this.profiles = profiles;
this.defaultProfile = defaultProfile;
}
public int getPriority(){
return priority;
}
public List<String> getMotd(){
return motd;
}
public List<String> getPlayers(){
return players;
}
public String getPlayerCount(){
return playerCount;
}
public String getFavicon(){
return favicon;
}
public boolean shouldHidePlayers(){
return hidePlayers;
}
public boolean isExtraPlayersEnabled(){
return extraPlayersEnabled;
}
public int getExtraPlayers(){
return extraPlayers;
}
public boolean evalConditions(Map<String, Object> replacements){
public boolean evaluateConditions(Map<String, Object> replacements){
if(expressions.isEmpty())
return true;
for(Expression expression : expressions){
if(!expression.evaluate(replacements)){
if(!expression.evaluate(replacements))
return false;
}
}
return true;
}
private List<Expression> createExpressions(List<String> list, PluginLogger logger) {
if(list.isEmpty())
return Collections.emptyList();
List<Expression> expressions = new ArrayList<>();
for(String str : list){
Expression expression = new Expression(str);
if(expression.getResult() != Expression.ExpressionResult.VALID){
logger.warn("Detected Invalid condition '%s'! Cause: %s", str, expression.getResult().getMessage());
continue;
}
expressions.add(expression);
public ProfileEntry getRandomProfile(){
if(profiles.isEmpty()){
return null;
}
return expressions;
if(profiles.size() == 1)
return profiles.get(0); // No need to run a random for 1 profile.
synchronized(random){
return profiles.get(random.nextInt(profiles.size()));
}
}
private List<String> getList(ConfigurationNode node, boolean trim, Object... path){
List<String> list;
try{
list = node.node(path).getList(String.class);
}catch(SerializationException ex){
return Collections.emptyList();
public ProfileEntry getDefaultProfile(){
return defaultProfile;
}
/*
* Returns true if the Profile...
* ...doesn't have any valid MOTD set AND
* ...doesn't have any player hover set AND
* ...doesn't have a player count text set and hidePlayers is false AND
* ...doesn't have a favicon set.
*/
public boolean isInvalidProfile(){
if(profiles.isEmpty())
return defaultProfile.isInvalidProfile();
boolean profilesValid = false;
for(ProfileEntry profile : profiles){
if(profile.isInvalidProfile())
continue;
profilesValid = true;
break;
}
return !profilesValid && defaultProfile.isInvalidProfile();
}
public static class Builder{
private final String fileName;
private final ConfigurationNode node;
private final int priority;
private final List<Expression> expressions = new ArrayList<>();
private final PluginLogger logger;
private List<ProfileEntry> profiles = new ArrayList<>();
private ProfileEntry defaultProfile = ProfileEntry.empty();
private Builder(String fileName, ConfigurationNode node, PluginLogger logger){
this.fileName = fileName;
this.node = node;
this.priority = node.node("priority").getInt();
this.logger = logger;
}
if(list == null)
return Collections.emptyList();
public static Builder resolve(String fileName, ConfigurationNode node, PluginLogger logger){
return new Builder(fileName, node, logger)
.resolveExpressions()
.resolveProfiles()
.resolveDefaultProfile();
}
if(trim && list.size() > 2)
return list.subList(0, 2);
private Builder resolveExpressions(){
List<String> temp;
try{
temp = node.node("conditions").getList(String.class);
}catch(SerializationException ex){
logger.warn("Encountered a SerializationException while resolving conditions for %s", ex, fileName);
return this;
}
if(temp == null || temp.isEmpty())
return this;
for(String str : temp){
Expression expr = new Expression(str);
if(expr.getResult() != Expression.ExpressionResult.VALID){
logger.warn("Found invalid expression in condition '%s'! Reason: %s", str, expr.getResult().getMessage());
continue;
}
this.expressions.add(expr);
}
return this;
}
return list;
private Builder resolveProfiles(){
try{
this.profiles = node.node("profiles").getList(ProfileEntry.class);
}catch(SerializationException ex){
logger.warn("Encountered a SerializationException while resolving the profiles entry for %s", ex, fileName);
}
return this;
}
private Builder resolveDefaultProfile(){
try{
this.defaultProfile = node.get(ProfileEntry.class);
}catch(SerializationException ex){
logger.warn("Encountered a SerializationException while resolving the global profile for %s", ex, fileName);
}
return this;
}
public ServerListProfile build(){
return new ServerListProfile(this.priority, this.expressions, this.profiles, this.defaultProfile);
}
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -70,22 +70,21 @@ public class Expression{
char next = (i == (chars.length - 1)) ? '\0' : chars[i + 1];
Operator tmp = Operator.getOperand(c, next);
if(tmp == Operator.UNKNOWN){
if(foundOperator){
right.append(c);
}else{
left.append(c);
}
if(tmp != Operator.UNKNOWN && !foundOperator){
operator = tmp;
foundOperator = true;
if(tmp.hasSecond())
i++; // Skip next character if operator has 2
continue;
}
if(foundOperator){
result = ExpressionResult.INVALID_DOUBLE_OPERATOR;
return;
right.append(c);
}else{
left.append(c);
}
operator = tmp;
foundOperator = true;
}
if(left.isEmpty() || right.isEmpty()){
@@ -193,9 +192,8 @@ public class Expression{
public enum ExpressionResult{
VALID(null),
INVALID_NO_EXPRESSION ("Received empty condition which isn't allowed!"),
INVALID_DOUBLE_OPERATOR("Condition contained two operands."),
INVALID_EMPTY_PARTS ("Received condition with either left or right part being empty.");
INVALID_NO_EXPRESSION("Received empty condition which isn't allowed!"),
INVALID_EMPTY_PARTS ("Received condition with either left or right part being empty.");
private final String message;
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -26,97 +26,133 @@
package ch.andre601.advancedserverlist.core.profiles.players;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.profiles.replacer.EntryList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import com.google.gson.Gson;
import io.leangen.geantyref.TypeToken;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.*;
public class PlayerHandler{
private final AdvancedServerList core;
private final PluginLogger logger;
private final Path cache;
private final EntryList<String, String> players = new EntryList<>();
private List<CachedPlayer> cachedPlayers = new ArrayList<>();
private final Type listType = new TypeToken<ArrayList<CachedPlayer>>(){}.getType();
private final Gson gson = new Gson();
// UUID of MHF_Question
private final String defaultUUID = "606e2ff0-ed77-4842-9d6c-e1d3321c7838";
private CachedPlayer defaultPlayer = null;
public PlayerHandler(AdvancedServerList core){
this.core = core;
this.cache = core.getPlugin().getFolderPath().resolve("cache.data");
this.logger = core.getPlugin().getPluginLogger();
this.cache = core.getPlugin().getFolderPath().resolve("playercache.json");
}
public void load(){
if(!cache.toFile().exists()){
core.getPlugin().getPluginLogger().info("No cache.data present. Skipping...");
logger.info("No playercache.json file present. Skipping...");
return;
}
List<String> lines;
if(core.getFileHandler().getBoolean("disable_cache")){
logger.info("'disable_cache' is set to true. Skipping playercache.json loading...");
return;
}
try{
lines = Files.readAllLines(cache);
Reader reader = Files.newBufferedReader(cache);
cachedPlayers = gson.fromJson(reader, listType);
reader.close();
}catch(IOException ex){
core.getPlugin().getPluginLogger().warn("Encountered IOException while trying to read cache.data", ex);
logger.warn("Encountered IOException while reading the playercache.json file!", ex);
return;
}
if(lines.isEmpty()){
core.getPlugin().getPluginLogger().info("cache.data is empty. Skipping...");
return;
}
for(String line : lines){
String[] parts = line.split("=", 2);
if(parts.length < 2 || parts[0].isEmpty() || parts[1].isEmpty())
continue;
if(players.containsKey(parts[0]))
continue;
players.add(parts[0], parts[1]);
}
core.getPlugin().getPluginLogger().info("Loaded " + players.size() + " players into cache!");
logger.info("Loaded %d players into cache!", cachedPlayers.size());
}
public void save(){
if(players.isEmpty()){
core.getPlugin().getPluginLogger().info("No data to save. Skipping...");
if(cachedPlayers.isEmpty()){
logger.info("No players in cache to save. Skipping...");
return;
}
StringJoiner joiner = new StringJoiner("\n");
for(Map.Entry<String, String> entry : players){
joiner.add(entry.getKey() + "=" + entry.getValue());
if(core.getFileHandler().getBoolean("disable_cache")){
logger.info("'disable_cache' is set to true. Skipping saving of cached players...");
return;
}
try{
BufferedWriter writer = Files.newBufferedWriter(cache, StandardCharsets.UTF_8, StandardOpenOption.WRITE);
writer.write(joiner.toString());
writer.close();
core.getPlugin().getPluginLogger().info("Successfully saved cache.data file.");
try(BufferedWriter writer = Files.newBufferedWriter(cache, StandardCharsets.UTF_8)){
gson.toJson(cachedPlayers, listType, writer);
logger.info("Successfully saved playercache.json file.");
}catch(IOException ex){
core.getPlugin().getPluginLogger().warn("Cannot save player data to cache.data file!", ex);
logger.warn("Encountered IOException while saving cached players to playercache.json!", ex);
}
}
public void addPlayer(String name, String ip){
if(players.containsKey(name))
public void addPlayer(String ip, String name, UUID uuid){
if(contains(ip) || core.getFileHandler().getBoolean("disable_cache"))
return;
players.add(name, ip);
cachedPlayers.add(new CachedPlayer(ip, name, uuid));
}
public String getPlayerByIp(String ip){
for(Map.Entry<String, String> entry : players){
if(entry.getValue().equals(ip))
return entry.getKey();
public CachedPlayer getCachedPlayer(String key){
if(!contains(key) || core.getFileHandler().getBoolean("disable_cache"))
return getDefaultPlayer();
for(CachedPlayer player : cachedPlayers){
if(player.getIp().equals(key))
return player;
}
return core.getFileHandler().getString("Anonymous", "unknown_player");
return getDefaultPlayer();
}
private boolean contains(String ip){
for(CachedPlayer player : cachedPlayers){
if(player.getIp().equals(ip))
return true;
}
return false;
}
private CachedPlayer getDefaultPlayer(){
if(defaultPlayer != null)
return defaultPlayer;
return (defaultPlayer = new CachedPlayer(
"0.0.0.0",
core.getFileHandler().getString("Anonymous", "unknown_player"),
convertToUUID(core.getFileHandler().getString(defaultUUID, "unknown_player_uuid"))
));
}
private UUID convertToUUID(String uuid){
try{
return UUID.fromString(uuid);
}catch(IllegalArgumentException ex){
// This is always a valid UUID.
return UUID.fromString(defaultUUID);
}
}
}
@@ -0,0 +1,194 @@
/*
* 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();
}
}
}
}
@@ -0,0 +1,137 @@
/*
* 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.AdvancedServerList;
import ch.andre601.advancedserverlist.core.objects.NullBool;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ProfileManager{
private final AdvancedServerList core;
private final Map<String, Object> replacements = new HashMap<>();
private ProfileManager(AdvancedServerList core){
this.core = core;
}
public static ProfileManager get(AdvancedServerList core){
return new ProfileManager(core);
}
public ProfileManager replacements(Placeholders placeholders){
this.replacements.putAll(placeholders.getReplacements());
return this;
}
public ServerListProfile getProfile(){
for(ServerListProfile profile : core.getFileHandler().getProfiles()){
if(profile.isInvalidProfile())
continue;
if(profile.evaluateConditions(replacements))
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.
*/
public static ProfileEntry merge(ServerListProfile profile){
ProfileEntry entry = profile.getRandomProfile();
ProfileEntry defEntry = profile.getDefaultProfile();
List<String> motd = resolveMOTD(entry, defEntry);
List<String> players = resolvePlayers(entry, defEntry);
String playerCountText = resolvePlayerCountText(entry, defEntry);
String favicon = resolveFavicon(entry, defEntry);
boolean isHidePlayersEnabled = resolveHidePlayersEnabled(entry, defEntry);
boolean isExtraPlayersEnabled = resolveExtraPlayersEnabled(entry, defEntry);
Integer extraPlayersCount = resolveExtraPlayersCount(entry, defEntry);
return new ProfileEntry(motd, players, playerCountText, favicon,
new NullBool(isHidePlayersEnabled), new NullBool(isExtraPlayersEnabled), extraPlayersCount);
}
private static List<String> resolveMOTD(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.getMOTD().isEmpty())
return defaultProfile.getMOTD();
return profile.getMOTD();
}
private static List<String> resolvePlayers(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.getPlayers().isEmpty())
return defaultProfile.getPlayers();
return profile.getPlayers();
}
private static String resolvePlayerCountText(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.getPlayerCountText().isEmpty())
return defaultProfile.getPlayerCountText();
return profile.getPlayerCountText();
}
private static String resolveFavicon(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.getFavicon().isEmpty())
return defaultProfile.getFavicon();
return profile.getFavicon();
}
private static boolean resolveHidePlayersEnabled(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.isHidePlayersEnabled().isNull())
return defaultProfile.isHidePlayersEnabled().getValue(false);
return profile.isHidePlayersEnabled().getValue(false);
}
private static boolean resolveExtraPlayersEnabled(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.isExtraPlayersEnabled().isNull())
return defaultProfile.isExtraPlayersEnabled().getValue(false);
return profile.isExtraPlayersEnabled().getValue(false);
}
private static Integer resolveExtraPlayersCount(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.getExtraPlayersCount() == null)
return defaultProfile.getExtraPlayersCount() == null ? 0 : defaultProfile.getExtraPlayersCount();
return profile.getExtraPlayersCount();
}
}
@@ -0,0 +1,58 @@
/*
* 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 org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.serialize.TypeSerializer;
import java.lang.reflect.Type;
public class ProfileSerializer implements TypeSerializer<ProfileEntry>{
public static final ProfileSerializer INSTANCE = new ProfileSerializer();
@Override
public ProfileEntry deserialize(Type type, ConfigurationNode node){
return ProfileEntry.Builder.resolve(node).build();
}
@Override
public void serialize(Type type, @Nullable ProfileEntry profile, ConfigurationNode node) throws SerializationException{
if(profile == null){
node.raw(null);
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());
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -37,6 +37,7 @@ public class PlayerPlaceholders implements Placeholders{
public PlayerPlaceholders(GenericPlayer<?> player){
this.replacements.put("${player name}", player.getName());
this.replacements.put("${player protocol}", player.getProtocol());
this.replacements.put("${player uuid}", player.getUniqueId());
if(player.getVersion() != null)
this.replacements.put("${player version}", player.getVersion());
@@ -47,7 +48,6 @@ public class PlayerPlaceholders implements Placeholders{
this.replacements.put("${player hasPlayedBefore}", player.hasPlayedBefore());
this.replacements.put("${player isBanned}", player.isBanned());
this.replacements.put("${player isWhitelisted}", player.isWhitelisted());
this.replacements.put("${player uuid}", player.getUniqueId());
}
@Override
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
+31 -1
View File
@@ -1,4 +1,34 @@
#
# Used for when AdvancedServerList doesn't have a cached player to use for ${player name}
#
unknown_player: "Anonymous"
# Defaults to 'Anonymous' when not present.
#
unknown_player: "Anonymous"
#
# UUID used for when AdvancedServerList doesn't have a cached player to use for the ${player uuid}
# placeholder.
#
# Defaults to the UUID of MHF_Question (606e2ff0-ed77-4842-9d6c-e1d3321c7838) when not present.
#
unknown_player_uuid: "606e2ff0-ed77-4842-9d6c-e1d3321c7838"
#
# Should the Caching of players be disabled?
#
# When set to true will AdvancedServerList not load any players from the cache.data file (if present) nor save any to it.
# Placeholders that rely on the player being cached (such as ${player isWhitelisted}) will not work while this option is enabled.
#
# Defaults to false when not present.
#
disable_cache: false
#
# Should AdvancedServerList check for new versions?
#
# When set to true will AdvancedServerList check for a new version on modrinth.com every 12 hours and inform you in the
# console about whether it found any new update or not.
#
# Defaults to false when not present.
#
check_updates: true
+38 -5
View File
@@ -16,24 +16,54 @@ priority: 0
# - '{playerVersion} < 759'
#
# Set the MOTD that should be displayed.
# Option that allows you to define multiple profiles to use.
# Each entry supports the same options as the server list profile does. Whenever an option is not present, or set to
# an empty value (If supported) would the option in the file be used (if present).
# This allows you to f.e. randomize the MOTD while keeping other options the same, without copy-pasting the same options.
#
# A profile will be selected randomly.
#
# Remove this option or set it to profiles: [] to use the global options of this file.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#profiles
#
#profiles:
# - motd:
# - '<aqua>Line 1'
# - '<aqua>Line 2'
# favicon: ''
# playerCount:
# hidePlayers: false
# hover:
# - '<green>Line 1'
# - '<green>Line 2'
# - '<green>Line 3'
# text: ''
# extraPlayers:
# enabled: false
# amount: 0
#
# Set the default (Global) MOTD used by this server list profile.
# Supports HEX colors for 1.16+ servers including gradients using MiniMessage's <gradient:color:color> format.
#
# Remove this option or set it to motd: [] to not alter the MOTD.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#motd
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#motds
#
motd:
- '<grey>Line 1'
- '<grey>Line 2'
#
# Allows you to set a favicon for this server list profile.
# Allows you to set a global (Default) favicon for this server list profile.
# You can use one of three possible options:
# 1. A file name matching a PNG file located in the 'favicons' folder (Needs to end with .png)
# 2. A URL pointing to a valid Image
# 3. ${player name} to display the player's head as favicon. Uses https://mc-heads.net for this
#
# Remove this option or set to favicon: '' to not replace the Favicon.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#favicon
#
favicon: ''
@@ -50,12 +80,15 @@ playerCount:
#
# Note that when this is enabled will all other options, except for 'extraPlayers', be ignored.
#
# Defaults to false when not present.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#hideplayers
#
hidePlayers: false
#
# Sets the text displayed when hovering over the player count.
# You can set this to 'hover: []' or remove the option to not modify the hover text.
#
# Remove this option or set it to hover: [] to not modify the player samples on the player count.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#hover
#
@@ -69,7 +102,7 @@ playerCount:
# Note that when used, the Ping icon will display as 'outdated server'/'outdated client'.
# This is nothing that can be fixed or avoided and would require changes from Mojang.
#
# You can set this to 'count: ''' or remove the option to not modify the player count text.
# Remove this option or set it to text: '' to not modify the player count text.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#text
#
+1 -1
View File
@@ -1,7 +1,7 @@
#
# MIT License
#
# Copyright (c) 2022 Andre_601
# 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
@@ -0,0 +1,292 @@
/*
* 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.test;
import com.unascribed.flexver.FlexVerComparator;
import org.junit.Test;
public class FlexVerTests{
private final String baseVersion = "1.0.0";
private final String versionMinor = "1.0.1";
private final String versionMajor = "1.1.0";
private final String versionBoth = "1.1.1";
private final String versionBeta = "1.0.0-b1";
private final String versionBetaMinor = "1.0.1-b1";
private final String versionBetaMajor = "1.1.0-b1";
private final String versionBetaBoth = "1.1.1-b1";
private final String versionBeta2 = "1.0.0-b2";
private final String versionBeta2Minor = "1.0.1-b2";
private final String versionBeta2Major = "1.1.0-b2";
private final String versionBeta2Both = "1.1.1-b2";
@Test
public void testFlexVerChecks(){
System.out.println("START: Version comparison Tests");
compareBaseVersion();
compareMinorVersion();
compareMajorVersion();
compareBothVersion();
compareBetaVersion();
compareBetaMinorVersion();
compareBetaMajorVersion();
compareBetaBothVersion();
compareBeta2Version();
compareBeta2MinorVersion();
compareBeta2MajorVersion();
compareBeta2BothVersion();
System.out.println("END: Version comparison Tests");
}
private void compareBaseVersion(){
System.out.println("┌────────────────────────────────┐");
System.out.println("│ Normal Version │");
System.out.println("│ │");
compare(baseVersion, "=", baseVersion, 0);
compare(baseVersion, "<", versionMinor, -1);
compare(baseVersion, "<", versionMajor, -1);
compare(baseVersion, "<", versionBoth, -1);
compare(baseVersion, ">", versionBeta, 1);
compare(baseVersion, "<", versionBetaMinor, -1);
compare(baseVersion, "<", versionBetaMajor, -1);
compare(baseVersion, "<", versionBetaBoth, -1);
compare(baseVersion, ">", versionBeta2, 1);
compare(baseVersion, "<", versionBeta2Minor, -1);
compare(baseVersion, "<", versionBeta2Major, -1);
compare(baseVersion, "<", versionBeta2Both, -1);
System.out.println("├────────────────────────────────┤");
}
private void compareMinorVersion(){
System.out.println("│ Minor Version │");
System.out.println("│ │");
compare(versionMinor, ">", baseVersion, 1);
compare(versionMinor, "=", versionMinor, 0);
compare(versionMinor, "<", versionMajor, -1);
compare(versionMinor, "<", versionBoth, -1);
compare(versionMinor, ">", versionBeta, 1);
compare(versionMinor, ">", versionBetaMinor, 1);
compare(versionMinor, "<", versionBetaMajor, -1);
compare(versionMinor, "<", versionBetaBoth, -1);
compare(versionMinor, ">", versionBeta2, 1);
compare(versionMinor, ">", versionBeta2Minor, 1);
compare(versionMinor, "<", versionBeta2Major, -1);
compare(versionMinor, "<", versionBeta2Both, -1);
System.out.println("├────────────────────────────────┤");
}
private void compareMajorVersion(){
System.out.println("│ Major Version │");
System.out.println("│ │");
compare(versionMajor, ">", baseVersion, 1);
compare(versionMajor, ">", versionMinor, 1);
compare(versionMajor, "=", versionMajor, 0);
compare(versionMajor, "<", versionBoth, -1);
compare(versionMajor, ">", versionBeta, 1);
compare(versionMajor, ">", versionBetaMinor, 1);
compare(versionMajor, ">", versionBetaMajor, 1);
compare(versionMajor, "<", versionBetaBoth, -1);
compare(versionMajor, ">", versionBeta2, 1);
compare(versionMajor, ">", versionBeta2Minor, 1);
compare(versionMajor, ">", versionBeta2Major, 1);
compare(versionMajor, "<", versionBeta2Both, -1);
System.out.println("├────────────────────────────────┤");
}
private void compareBothVersion(){
System.out.println("│ Major + Minor Version │");
System.out.println("│ │");
compare(versionBoth, ">", baseVersion, 1);
compare(versionBoth, ">", versionMinor, 1);
compare(versionBoth, ">", versionMajor, 1);
compare(versionBoth, "=", versionBoth, 0);
compare(versionBoth, ">", versionBeta, 1);
compare(versionBoth, ">", versionBetaMinor, 1);
compare(versionBoth, ">", versionBetaMajor, 1);
compare(versionBoth, ">", versionBetaBoth, 1);
compare(versionBoth, ">", versionBeta2, 1);
compare(versionBoth, ">", versionBeta2Minor, 1);
compare(versionBoth, ">", versionBeta2Major, 1);
compare(versionBoth, ">", versionBeta2Both, 1);
System.out.println("├────────────────────────────────┤");
}
private void compareBetaVersion(){
System.out.println("│ Beta Version │");
System.out.println("│ │");
compare(versionBeta, "<", baseVersion, -1);
compare(versionBeta, "<", versionMinor, -1);
compare(versionBeta, "<", versionMajor, -1);
compare(versionBeta, "<", versionBoth, -1);
compare(versionBeta, "=", versionBeta, 0);
compare(versionBeta, "<", versionBetaMinor, -1);
compare(versionBeta, "<", versionBetaMajor, -1);
compare(versionBeta, "<", versionBetaBoth, -1);
compare(versionBeta, "<", versionBeta2, -1);
compare(versionBeta, "<", versionBeta2Minor, -1);
compare(versionBeta, "<", versionBeta2Major, -1);
compare(versionBeta, "<", versionBeta2Both, -1);
System.out.println("├────────────────────────────────┤");
}
private void compareBetaMinorVersion(){
System.out.println("│ Beta Version Minor │");
System.out.println("│ │");
compare(versionBetaMinor, ">", baseVersion, 1);
compare(versionBetaMinor, "<", versionMinor, -1);
compare(versionBetaMinor, "<", versionMajor, -1);
compare(versionBetaMinor, "<", versionBoth, -1);
compare(versionBetaMinor, ">", versionBeta, 1);
compare(versionBetaMinor, "=", versionBetaMinor, 0);
compare(versionBetaMinor, "<", versionBetaMajor, -1);
compare(versionBetaMinor, "<", versionBetaBoth, -1);
compare(versionBetaMinor, ">", versionBeta2, 1);
compare(versionBetaMinor, "<", versionBeta2Minor, -1);
compare(versionBetaMinor, "<", versionBeta2Major, -1);
compare(versionBetaMinor, "<", versionBeta2Both, -1);
System.out.println("├────────────────────────────────┤");
}
private void compareBetaMajorVersion(){
System.out.println("│ Beta Version Major │");
System.out.println("│ │");
compare(versionBetaMajor, ">", baseVersion, 1);
compare(versionBetaMajor, ">", versionMinor, 1);
compare(versionBetaMajor, "<", versionMajor, -1);
compare(versionBetaMajor, "<", versionBoth, -1);
compare(versionBetaMajor, ">", versionBeta, 1);
compare(versionBetaMajor, ">", versionBetaMinor, 1);
compare(versionBetaMajor, "=", versionBetaMajor, 0);
compare(versionBetaMajor, "<", versionBetaBoth, -1);
compare(versionBetaMajor, ">", versionBeta2, 1);
compare(versionBetaMajor, ">", versionBeta2Minor, 1);
compare(versionBetaMajor, "<", versionBeta2Major, -1);
compare(versionBetaMajor, "<", versionBeta2Both, -1);
System.out.println("├────────────────────────────────┤");
}
private void compareBetaBothVersion(){
System.out.println("│ Beta Version Major + Minor │");
System.out.println("│ │");
compare(versionBetaBoth, ">", baseVersion, 1);
compare(versionBetaBoth, ">", versionMinor, 1);
compare(versionBetaBoth, ">", versionMajor, 1);
compare(versionBetaBoth, "<", versionBoth, -1);
compare(versionBetaBoth, ">", versionBeta, 1);
compare(versionBetaBoth, ">", versionBetaMinor, 1);
compare(versionBetaBoth, ">", versionBetaMajor, 1);
compare(versionBetaBoth, "=", versionBetaBoth, 0);
compare(versionBetaBoth, ">", versionBeta2, 1);
compare(versionBetaBoth, ">", versionBeta2Minor, 1);
compare(versionBetaBoth, ">", versionBeta2Major, 1);
compare(versionBetaBoth, "<", versionBeta2Both, -1);
System.out.println("├────────────────────────────────┤");
}
private void compareBeta2Version(){
System.out.println("│ Beta Version 2 │");
System.out.println("│ │");
compare(versionBeta2, "<", baseVersion, -1);
compare(versionBeta2, "<", versionMinor, -1);
compare(versionBeta2, "<", versionMajor, -1);
compare(versionBeta2, "<", versionBoth, -1);
compare(versionBeta2, ">", versionBeta, 1);
compare(versionBeta2, "<", versionBetaMinor, -1);
compare(versionBeta2, "<", versionBetaMajor, -1);
compare(versionBeta2, "<", versionBetaBoth, -1);
compare(versionBeta2, "=", versionBeta2, 0);
compare(versionBeta2, "<", versionBeta2Minor, -1);
compare(versionBeta2, "<", versionBeta2Major, -1);
compare(versionBeta2, "<", versionBeta2Both, -1);
System.out.println("├────────────────────────────────┤");
}
private void compareBeta2MinorVersion(){
System.out.println("│ Beta Version 2 Minor │");
System.out.println("│ │");
compare(versionBeta2Minor, ">", baseVersion, 1);
compare(versionBeta2Minor, "<", versionMinor, -1);
compare(versionBeta2Minor, "<", versionMajor, -1);
compare(versionBeta2Minor, "<", versionBoth, -1);
compare(versionBeta2Minor, ">", versionBeta, 1);
compare(versionBeta2Minor, ">", versionBetaMinor, 1);
compare(versionBeta2Minor, "<", versionBetaMajor, -1);
compare(versionBeta2Minor, "<", versionBetaBoth, -1);
compare(versionBeta2Minor, ">", versionBeta2, 1);
compare(versionBeta2Minor, "=", versionBeta2Minor, 0);
compare(versionBeta2Minor, "<", versionBeta2Major, -1);
compare(versionBeta2Minor, "<", versionBeta2Both, -1);
System.out.println("├────────────────────────────────┤");
}
private void compareBeta2MajorVersion(){
System.out.println("│ Beta Version 2 Major │");
System.out.println("│ │");
compare(versionBeta2Major, ">", baseVersion, 1);
compare(versionBeta2Major, ">", versionMinor, 1);
compare(versionBeta2Major, "<", versionMajor, -1);
compare(versionBeta2Major, "<", versionBoth, -1);
compare(versionBeta2Major, ">", versionBeta, 1);
compare(versionBeta2Major, ">", versionBetaMinor, 1);
compare(versionBeta2Major, ">", versionBetaMajor, 1);
compare(versionBeta2Major, "<", versionBetaBoth, -1);
compare(versionBeta2Major, ">", versionBeta2, 1);
compare(versionBeta2Major, ">", versionBeta2Minor, 1);
compare(versionBeta2Major, "=", versionBeta2Major, 0);
compare(versionBeta2Major, "<", versionBeta2Both, -1);
System.out.println("├────────────────────────────────┤");
}
private void compareBeta2BothVersion(){
System.out.println("│ Beta Version 2 Major + Minor │");
System.out.println("│ │");
compare(versionBeta2Both, ">", baseVersion, 1);
compare(versionBeta2Both, ">", versionMinor, 1);
compare(versionBeta2Both, ">", versionMajor, 1);
compare(versionBeta2Both, "<", versionBoth, -1);
compare(versionBeta2Both, ">", versionBeta, 1);
compare(versionBeta2Both, ">", versionBetaMinor, 1);
compare(versionBeta2Both, ">", versionBetaMajor, 1);
compare(versionBeta2Both, ">", versionBetaBoth, 1);
compare(versionBeta2Both, ">", versionBeta2, 1);
compare(versionBeta2Both, ">", versionBeta2Minor, 1);
compare(versionBeta2Both, ">", versionBeta2Major, 1);
compare(versionBeta2Both, "=", versionBeta2Both, 0);
System.out.println("└────────────────────────────────┘");
}
private void compare(String version1, String comparator, String version2, int expected){
String expression = version1 + " " + comparator + " " + version2 + "?";
System.out.printf("│ %-24s %5b │\n", expression, FlexVerComparator.compare(version1, version2) == expected);
}
}
+2 -2
View File
@@ -2,7 +2,7 @@
<!--
~ MIT License
~
~ Copyright (c) 2022 Andre_601
~ 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
@@ -101,7 +101,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -67,18 +67,7 @@ public class PaperCore extends JavaPlugin implements ServerCore<CachedServerIcon
Class.forName("com.destroystokyo.paper.PaperConfig");
enable();
}catch(ClassNotFoundException ex1){
getPluginLogger().warn("======================================== WARNING ========================================");
getPluginLogger().warn("");
getPluginLogger().warn("You are using the PaperMC version of AdvancedServerList on a SpigotMC server.");
getPluginLogger().warn("The PaperMC version is ONLY compatible with PaperMC 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 PaperMC or use the Spigot version");
getPluginLogger().warn("of AdvancedServerList.");
getPluginLogger().warn("");
getPluginLogger().warn("======================================== WARNING ========================================");
printSpigotWarning();
getServer().getPluginManager().disablePlugin(this);
}
}
@@ -117,6 +106,9 @@ public class PaperCore extends JavaPlugin implements ServerCore<CachedServerIcon
@Override
public void clearFaviconCache(){
if(faviconHandler == null)
return;
faviconHandler.clearCache();
}
@@ -153,8 +145,9 @@ public class PaperCore extends JavaPlugin implements ServerCore<CachedServerIcon
return getServer().getVersion();
}
private void enable(){
this.core = new AdvancedServerList(this);
@Override
public String getLoader(){
return "paper";
}
@Override
@@ -178,4 +171,25 @@ public class PaperCore extends JavaPlugin implements ServerCore<CachedServerIcon
return players;
}
private void enable(){
this.core = new AdvancedServerList(this);
}
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,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -25,23 +25,25 @@
package ch.andre601.advancedserverlist.paper;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
import org.bukkit.OfflinePlayer;
public class PaperPlayer extends GenericPlayer<OfflinePlayer>{
public PaperPlayer(OfflinePlayer player, String name, int protocol){
public PaperPlayer(OfflinePlayer player, CachedPlayer cachedPlayer, int protocol){
this.player = player;
this.name = player == null ? name : player.getName();
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();
this.uuid = player.getUniqueId();
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -26,6 +26,7 @@
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;
@@ -46,7 +47,8 @@ public class JoinEvent implements Listener{
InetSocketAddress address = event.getPlayer().getAddress();
if(address == null)
return;
plugin.getCore().getPlayerHandler().addPlayer(event.getPlayer().getName(), address.getHostString());
Player player = event.getPlayer();
plugin.getCore().getPlayerHandler().addPlayer(address.getHostString(), player.getName(), player.getUniqueId());
}
}
@@ -0,0 +1,155 @@
/*
* 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.core.interfaces.events.GenericEventWrapper;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
import ch.andre601.advancedserverlist.paper.PaperCore;
import ch.andre601.advancedserverlist.paper.PaperPlayer;
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
import me.clip.placeholderapi.PlaceholderAPI;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.util.CachedServerIcon;
import java.awt.image.BufferedImage;
import java.util.List;
public class PaperEventWrapper implements GenericEventWrapper<OfflinePlayer, CachedServerIcon>{
private final PaperCore plugin;
private final PaperServerListPingEvent event;
public PaperEventWrapper(PaperCore plugin, PaperServerListPingEvent event){
this.plugin = plugin;
this.event = event;
}
@Override
public void setMaxPlayers(int maxPlayers){
event.setMaxPlayers(maxPlayers);
}
@Override
public void setMotd(Component component){
event.motd(component);
}
@Override
public void hidePlayers(){
event.setHidePlayers(true);
}
@Override
public void setPlayerCount(String name){
event.setVersion(name);
event.setProtocolVersion(-1);
}
@Override
public void setPlayers(List<String> players, GenericPlayer<OfflinePlayer> player, PlayerPlaceholders playerPlaceholders, ServerPlaceholders serverPlaceholders){
event.getPlayerSample().clear();
event.getPlayerSample().addAll(
plugin.createPlayers(players, player.getPlayer(), playerPlaceholders, serverPlaceholders)
);
}
@Override
public void setFavicon(CachedServerIcon favicon){
event.setServerIcon(favicon);
}
@Override
public void setDefaultFavicon(){
event.setServerIcon(event.getServerIcon());
}
// Not used in Paper
@Override
public void updateEvent(){}
// Not used in Paper
@Override
public boolean isInvalidProtocol(){
return false;
}
@Override
public int getProtocolVersion(){
return event.getClient().getProtocolVersion();
}
@Override
public int getOnlinePlayers(){
return event.getNumPlayers();
}
@Override
public int getMaxPlayers(){
return event.getMaxPlayers();
}
@Override
public String getPlayerIP(){
return event.getClient().getAddress().getHostString();
}
@Override
public String parsePAPIPlaceholders(String text, GenericPlayer<OfflinePlayer> player){
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
return text;
}
@Override
public String getVirtualHost(){
return this.resolveHost(event.getClient().getVirtualHost());
}
@Override
public PluginCore<CachedServerIcon> getPlugin(){
return plugin;
}
@Override
public GenericPlayer<OfflinePlayer> createPlayer(CachedPlayer player, int protocol){
OfflinePlayer pl = Bukkit.getOfflinePlayer(player.getUuid());
return new PaperPlayer(pl.hasPlayedBefore() ? pl : null, player, protocol);
}
@Override
public CachedServerIcon createFavicon(BufferedImage image) throws Exception{
return Bukkit.loadServerIcon(image);
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -25,23 +25,11 @@
package ch.andre601.advancedserverlist.paper.events;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.ProfileManager;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import ch.andre601.advancedserverlist.paper.PaperCore;
import ch.andre601.advancedserverlist.paper.PaperPlayer;
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.util.CachedServerIcon;
import java.net.InetSocketAddress;
public class PingEvent implements Listener{
@@ -54,101 +42,6 @@ public class PingEvent implements Listener{
@EventHandler
public void onServerPing(PaperServerListPingEvent event){
InetSocketAddress address = event.getClient().getAddress();
InetSocketAddress host = event.getClient().getVirtualHost();
PaperPlayer player = resolvePlayer(address, event.getClient().getProtocolVersion());
int online = event.getNumPlayers();
int max = event.getMaxPlayers();
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(player);
ServerPlaceholders serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
ServerListProfile profile = ProfileManager.get(plugin.getCore())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.getProfile();
if(profile == null)
return;
if(profile.isExtraPlayersEnabled()){
max = online + profile.getExtraPlayers();
event.setMaxPlayers(max);
}
serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
if(!profile.getMotd().isEmpty()){
event.motd(ComponentParser.list(profile.getMotd())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.modifyText(text -> {
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
return text;
})
.toComponent());
}
if(profile.shouldHidePlayers()){
event.setHidePlayers(true);
}
if(!profile.getPlayerCount().isEmpty() && !profile.shouldHidePlayers()){
event.setVersion(ComponentParser.text(profile.getPlayerCount())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.modifyText(text -> {
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
return text;
})
.toString());
event.setProtocolVersion(-1);
}
if(!profile.getPlayers().isEmpty() && !profile.shouldHidePlayers()){
event.getPlayerSample().clear();
event.getPlayerSample().addAll(
plugin.createPlayers(profile.getPlayers(), player.getPlayer(), playerPlaceholders, serverPlaceholders)
);
}
if(!profile.getFavicon().isEmpty()){
String favName = StringReplacer.replace(profile.getFavicon(), playerPlaceholders.getReplacements());
CachedServerIcon favicon = plugin.getFaviconHandler().getFavicon(favName, image -> {
try{
return Bukkit.loadServerIcon(image);
}catch(Exception ex){
return null;
}
});
if(favicon == null){
plugin.getPluginLogger().warn("Could not obtain valid Favicon to use.");
event.setServerIcon(event.getServerIcon());
}else{
event.setServerIcon(favicon);
}
}
}
private PaperPlayer resolvePlayer(InetSocketAddress address, int protocol){
String playerName = plugin.getCore().getPlayerHandler().getPlayerByIp(address.getHostString());
OfflinePlayer player = Bukkit.getPlayerExact(playerName);
if(player == null){
player = Bukkit.getOfflinePlayer(playerName);
return new PaperPlayer(player.hasPlayedBefore() ? player : null, playerName, protocol);
}
return new PaperPlayer(player, playerName, protocol);
PingEventHandler.handleEvent(new PaperEventWrapper(plugin, event));
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -52,4 +52,9 @@ public class PaperLogger implements PluginLogger{
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);
}
}
+3
View File
@@ -7,6 +7,9 @@ main: 'ch.andre601.advancedserverlist.paper.PaperCore'
api-version: 1.19
libraries:
- 'com.squareup.okhttp3:okhttp:4.10.0'
softdepend:
- 'PlaceholderAPI'
+27 -2
View File
@@ -1,4 +1,29 @@
<?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">
@@ -12,7 +37,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<plugin.version>1.6.0</plugin.version>
<plugin.version>1.11.0</plugin.version>
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
<maven.compiler.source>16</maven.compiler.source>
@@ -21,10 +46,10 @@
<modules>
<module>core</module>
<module>velocity</module>
<module>bungeecord</module>
<module>paper</module>
<module>spigot</module>
<module>velocity</module>
</modules>
</project>
+3 -3
View File
@@ -2,7 +2,7 @@
<!--
~ MIT License
~
~ Copyright (c) 2022 Andre_601
~ 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
@@ -74,7 +74,7 @@
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-bukkit</artifactId>
<version>4.1.2</version>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>com.comphenix.protocol</groupId>
@@ -116,7 +116,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.0</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -102,6 +102,9 @@ public class SpigotCore extends JavaPlugin implements ServerCore<WrappedServerPi
@Override
public void clearFaviconCache(){
if(faviconHandler == null)
return;
faviconHandler.clearCache();
}
@@ -138,6 +141,11 @@ public class SpigotCore extends JavaPlugin implements ServerCore<WrappedServerPi
return getServer().getVersion();
}
@Override
public String getLoader(){
return "spigot";
}
@Override
public List<WrappedGameProfile> createPlayers(List<String> lines, OfflinePlayer player, Placeholders... placeholders){
List<WrappedGameProfile> players = new ArrayList<>(lines.size());
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -25,23 +25,25 @@
package ch.andre601.advancedserverlist.spigot;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
import org.bukkit.OfflinePlayer;
public class SpigotPlayer extends GenericPlayer<OfflinePlayer>{
public SpigotPlayer(OfflinePlayer player, String name, int protocol){
public SpigotPlayer(OfflinePlayer player, CachedPlayer cachedPlayer, int protocol){
this.player = player;
this.name = player == null ? name : player.getName();
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();
this.uuid = player.getUniqueId();
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -26,6 +26,7 @@
package ch.andre601.advancedserverlist.spigot.events;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
@@ -45,7 +46,8 @@ public class JoinEvent implements Listener{
InetSocketAddress address = event.getPlayer().getAddress();
if(address == null)
return;
plugin.getCore().getPlayerHandler().addPlayer(event.getPlayer().getName(), address.getHostString());
Player player = event.getPlayer();
plugin.getCore().getPlayerHandler().addPlayer(address.getHostString(), player.getName(), player.getUniqueId());
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -25,39 +25,26 @@
package ch.andre601.advancedserverlist.spigot.events;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.ProfileManager;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import ch.andre601.advancedserverlist.spigot.SpigotPlayer;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.AdventureComponentConverter;
import com.comphenix.protocol.wrappers.WrappedServerPing;
import me.clip.placeholderapi.PlaceholderAPI;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.event.Listener;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
public class PingEvent implements Listener{
private final SpigotCore plugin;
private final ProtocolManager protocolManager;
private final Map<String, String> hostAddresses = new HashMap<>();
public PingEvent(SpigotCore plugin, ProtocolManager protocolManager){
this.plugin = plugin;
this.protocolManager = protocolManager;
loadPacketListener(plugin);
@@ -80,106 +67,8 @@ public class PingEvent implements Listener{
protocolManager.addPacketListener(new PacketAdapter(spigotPlugin, ListenerPriority.LOW, PacketType.Status.Server.SERVER_INFO){
@Override
public void onPacketSending(PacketEvent event){
WrappedServerPing ping = event.getPacket().getServerPings().read(0);
InetSocketAddress address = event.getPlayer().getAddress();
if(address == null)
return;
SpigotPlayer player = resolvePlayer(address, ping.getVersionProtocol());
int online = ping.getPlayersOnline();
int max = ping.getPlayersMaximum();
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(player);
ServerPlaceholders serverPlaceholders = new ServerPlaceholders(online, max, hostAddresses.get(address.getHostString()));
ServerListProfile profile = ProfileManager.get(spigotPlugin.getCore())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.getProfile();
if(profile == null)
return;
if(profile.isExtraPlayersEnabled()){
max = online + profile.getExtraPlayers();
ping.setPlayersMaximum(max);
}
serverPlaceholders = new ServerPlaceholders(online, max, hostAddresses.get(address.getHostString()));
if(!profile.getMotd().isEmpty()){
Component component = ComponentParser.list(profile.getMotd())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.modifyText(text -> {
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
return text;
})
.toComponent();
ping.setMotD(AdventureComponentConverter.fromComponent(component));
}
if(profile.shouldHidePlayers()){
ping.setPlayersVisible(false);
}
if(!profile.getPlayerCount().isEmpty() && !profile.shouldHidePlayers()){
ping.setVersionName(ComponentParser.text(profile.getPlayerCount())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.modifyText(text -> {
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
return text;
})
.toString()
);
ping.setVersionProtocol(-1);
}
if(!profile.getPlayers().isEmpty() && !profile.shouldHidePlayers()){
ping.setPlayers(
spigotPlugin.createPlayers(profile.getPlayers(), player.getPlayer(), playerPlaceholders, serverPlaceholders)
);
}
if(!profile.getFavicon().isEmpty()){
String favName = StringReplacer.replace(profile.getFavicon(), playerPlaceholders.getReplacements());
WrappedServerPing.CompressedImage favicon = spigotPlugin.getFaviconHandler().getFavicon(favName, image -> {
try{
return WrappedServerPing.CompressedImage.fromPng(image);
}catch(Exception ex){
return null;
}
});
if(favicon == null){
spigotPlugin.getPluginLogger().warn("Could not obtain valid Favicon to use.");
ping.setFavicon(ping.getFavicon());
}else{
ping.setFavicon(favicon);
}
}
PingEventHandler.handleEvent(new ProtocolLibEventWrapper(spigotPlugin, event, hostAddresses));
}
});
}
private SpigotPlayer resolvePlayer(InetSocketAddress address, int protocol){
String playerName = plugin.getCore().getPlayerHandler().getPlayerByIp(address.getHostString());
OfflinePlayer player = Bukkit.getPlayerExact(playerName);
if(player == null){
//noinspection deprecation
player = Bukkit.getOfflinePlayer(playerName);
return new SpigotPlayer(player.hasPlayedBefore() ? player : null, playerName, protocol);
}
return new SpigotPlayer(player, playerName, protocol);
}
}
@@ -0,0 +1,164 @@
/*
* 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.spigot.events;
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import ch.andre601.advancedserverlist.spigot.SpigotPlayer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.AdventureComponentConverter;
import com.comphenix.protocol.wrappers.WrappedServerPing;
import me.clip.placeholderapi.PlaceholderAPI;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.Map;
public class ProtocolLibEventWrapper implements GenericEventWrapper<OfflinePlayer, WrappedServerPing.CompressedImage>{
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){
this.plugin = plugin;
this.event = event;
this.ping = event.getPacket().getServerPings().read(0);
this.hostAddresses = hostAddresses;
}
@Override
public void setMaxPlayers(int maxPlayers){
ping.setPlayersMaximum(maxPlayers);
}
@Override
public void setMotd(Component component){
ping.setMotD(AdventureComponentConverter.fromComponent(component));
}
@Override
public void hidePlayers(){
ping.setPlayersVisible(false);
}
@Override
public void setPlayerCount(String name){
ping.setVersionName(name);
ping.setVersionProtocol(-1);
}
@Override
public void setPlayers(List<String> players, GenericPlayer<OfflinePlayer> player, PlayerPlaceholders playerPlaceholders, ServerPlaceholders serverPlaceholders){
ping.setPlayers(
plugin.createPlayers(players, player.getPlayer(), playerPlaceholders, serverPlaceholders)
);
}
@Override
public void setFavicon(WrappedServerPing.CompressedImage favicon){
ping.setFavicon(favicon);
}
@Override
public void setDefaultFavicon(){
ping.setFavicon(ping.getFavicon());
}
// Not used in ProtocolLib
@Override
public void updateEvent(){}
@Override
public boolean isInvalidProtocol(){
return event.getPlayer().getAddress() == null;
}
@Override
public int getProtocolVersion(){
return ping.getVersionProtocol();
}
@Override
public int getOnlinePlayers(){
return ping.getPlayersOnline();
}
@Override
public int getMaxPlayers(){
return ping.getPlayersMaximum();
}
@Override
public String getPlayerIP(){
return event.getPlayer().getAddress() == null ? "UNKNOWN" : event.getPlayer().getAddress().getHostString();
}
@Override
public String parsePAPIPlaceholders(String text, GenericPlayer<OfflinePlayer> player){
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
return text;
}
@Override
public String getVirtualHost(){
String host = this.resolveHost(event.getPlayer().getAddress());
if(host == null)
return null;
return hostAddresses.get(host);
}
@Override
public PluginCore<WrappedServerPing.CompressedImage> getPlugin(){
return plugin;
}
@Override
public GenericPlayer<OfflinePlayer> createPlayer(CachedPlayer player, int protocol){
OfflinePlayer pl = Bukkit.getOfflinePlayer(player.getUuid());
return new SpigotPlayer(pl.hasPlayedBefore() ? pl : null, player, protocol);
}
@Override
public WrappedServerPing.CompressedImage createFavicon(BufferedImage image) throws Exception{
return WrappedServerPing.CompressedImage.fromPng(image);
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -52,4 +52,9 @@ public class SpigotLogger implements PluginLogger{
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);
}
}
+5 -4
View File
@@ -9,10 +9,11 @@ api-version: 1.19
libraries:
- 'org.spongepowered:configurate-yaml:4.1.2'
- 'net.kyori:adventure-api:4.11.0'
- 'net.kyori:adventure-text-minimessage:4.11.0'
- 'net.kyori:adventure-text-serializer-legacy:4.11.0'
- 'net.kyori:adventure-platform-bukkit:4.1.2'
- 'net.kyori:adventure-api:4.12.0'
- 'net.kyori:adventure-text-minimessage:4.12.0'
- 'net.kyori:adventure-text-serializer-legacy:4.12.0'
- 'net.kyori:adventure-platform-bukkit:4.2.0'
- 'com.squareup.okhttp3:okhttp:4.10.0'
softdepend:
- 'ProtocolLib'
+6 -2
View File
@@ -2,7 +2,7 @@
<!--
~ MIT License
~
~ Copyright (c) 2022 Andre_601
~ 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
@@ -88,7 +88,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<version>3.4.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
@@ -104,6 +104,10 @@
<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>
</relocation>
</relocations>
<filters>
<filter>
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -26,8 +26,8 @@
package ch.andre601.advancedserverlist.velocity;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.core.ProxyCore;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.interfaces.core.ProxyCore;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
@@ -107,6 +107,9 @@ public class VelocityCore implements ProxyCore<Favicon, ServerPing.SamplePlayer>
@Override
public void clearFaviconCache(){
if(faviconHandler == null)
return;
faviconHandler.clearCache();
}
@@ -159,6 +162,11 @@ public class VelocityCore implements ProxyCore<Favicon, ServerPing.SamplePlayer>
return getProxy().getVersion().getVersion();
}
@Override
public String getLoader(){
return "velocity";
}
public ProxyServer getProxy(){
return proxy;
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -25,15 +25,18 @@
package ch.andre601.advancedserverlist.velocity;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.Player;
public class VelocityPlayer extends GenericPlayer<Player>{
public VelocityPlayer(String name, int protocol){
this.name = name;
public VelocityPlayer(CachedPlayer player, int protocol){
this.name = player.getName();
this.protocol = protocol;
this.uuid = player.getUuid();
this.version = ProtocolVersion.getProtocolVersion(protocol).getVersionIntroducedIn();
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -28,6 +28,7 @@ package ch.andre601.advancedserverlist.velocity.events;
import ch.andre601.advancedserverlist.velocity.VelocityCore;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.PostLoginEvent;
import com.velocitypowered.api.proxy.Player;
import java.net.InetSocketAddress;
@@ -43,6 +44,8 @@ public class JoinEvent{
@Subscribe
public void onJoin(PostLoginEvent event){
InetSocketAddress address = event.getPlayer().getRemoteAddress();
plugin.getCore().getPlayerHandler().addPlayer(event.getPlayer().getUsername(), address.getHostString());
Player player = event.getPlayer();
plugin.getCore().getPlayerHandler().addPlayer(address.getHostString(), player.getUsername(), player.getUniqueId());
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -25,22 +25,11 @@
package ch.andre601.advancedserverlist.velocity.events;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.ProfileManager;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import ch.andre601.advancedserverlist.velocity.VelocityCore;
import ch.andre601.advancedserverlist.velocity.VelocityPlayer;
import com.velocitypowered.api.event.PostOrder;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
import com.velocitypowered.api.proxy.server.ServerPing;
import com.velocitypowered.api.util.Favicon;
import java.net.InetSocketAddress;
import java.util.List;
public class PingEvent{
@@ -53,85 +42,6 @@ public class PingEvent{
@Subscribe(order = PostOrder.EARLY)
public void onProxyPing(ProxyPingEvent event){
ServerPing ping = event.getPing();
ServerPing.Version protocol = ping.getVersion();
if(protocol == null)
return;
ServerPing.Builder builder = ping.asBuilder();
String playerName = plugin.getCore().getPlayerHandler().getPlayerByIp(event.getConnection().getRemoteAddress().getHostString());
InetSocketAddress host = event.getConnection().getVirtualHost().orElse(null);
int online = builder.getOnlinePlayers();
int max = builder.getMaximumPlayers();
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(new VelocityPlayer(playerName, protocol.getProtocol()));
ServerPlaceholders serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
ServerListProfile profile = ProfileManager.get(plugin.getCore())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.getProfile();
if(profile == null)
return;
if(profile.isExtraPlayersEnabled()){
max = online + profile.getExtraPlayers();
builder.maximumPlayers(max);
}
serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
if(!profile.getMotd().isEmpty()){
List<String> motd = profile.getMotd();
builder.description(ComponentParser.list(motd)
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.toComponent()
);
}
if(profile.shouldHidePlayers()){
builder.nullPlayers();
}
if(!profile.getPlayerCount().isEmpty() && !profile.shouldHidePlayers()){
builder.version(new ServerPing.Version(
-1,
ComponentParser.text(profile.getPlayerCount())
.replacements(playerPlaceholders)
.replacements(serverPlaceholders)
.toString()
));
}
if(!profile.getPlayers().isEmpty() && !profile.shouldHidePlayers()){
ServerPing.SamplePlayer[] playerSamples = plugin.createPlayers(profile.getPlayers(), playerPlaceholders, serverPlaceholders)
.toArray(new ServerPing.SamplePlayer[0]);
if(playerSamples.length > 0)
builder.clearSamplePlayers().samplePlayers(playerSamples);
}
if(!profile.getFavicon().isEmpty()){
String favName = StringReplacer.replace(profile.getFavicon(), playerPlaceholders.getReplacements());
Favicon favicon = plugin.getFaviconHandler().getFavicon(favName, image -> {
try{
return Favicon.create(image);
}catch(Exception ex){
return null;
}
});
if(favicon == null){
plugin.getPluginLogger().warn("Could not obtain valid Favicon to use.");
}else{
builder.favicon(favicon);
}
}
event.setPing(builder.build());
PingEventHandler.handleEvent(new VelocityEventWrapper(plugin, event));
}
}
@@ -0,0 +1,151 @@
/*
* 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.velocity.events;
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.profiles.players.GenericPlayer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
import ch.andre601.advancedserverlist.velocity.VelocityCore;
import ch.andre601.advancedserverlist.velocity.VelocityPlayer;
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.ServerPing;
import com.velocitypowered.api.util.Favicon;
import net.kyori.adventure.text.Component;
import java.awt.image.BufferedImage;
import java.util.List;
public class VelocityEventWrapper implements GenericEventWrapper<Player, Favicon>{
private final VelocityCore plugin;
private final ProxyPingEvent event;
private final ServerPing.Builder builder;
private final ServerPing.Version protocol;
public VelocityEventWrapper(VelocityCore plugin, ProxyPingEvent event){
this.plugin = plugin;
this.event = event;
this.builder = event.getPing().asBuilder();
this.protocol = event.getPing().getVersion();
}
@Override
public void setMaxPlayers(int maxPlayers){
builder.maximumPlayers(maxPlayers);
}
@Override
public void setMotd(Component component){
builder.description(component);
}
@Override
public void hidePlayers(){
builder.nullPlayers();
}
@Override
public void setPlayerCount(String name){
builder.version(new ServerPing.Version(-1, name));
}
@Override
public void setPlayers(List<String> players, GenericPlayer<Player> player, PlayerPlaceholders playerPlaceholders, ServerPlaceholders serverPlaceholders){
ServerPing.SamplePlayer[] playerSamples = plugin.createPlayers(players, playerPlaceholders, serverPlaceholders)
.toArray(new ServerPing.SamplePlayer[0]);
if(playerSamples.length > 0)
builder.clearSamplePlayers().samplePlayers(playerSamples);
}
@Override
public void setFavicon(Favicon favicon){
builder.favicon(favicon);
}
// Not used in Velocity
@Override
public void setDefaultFavicon(){}
@Override
public void updateEvent(){
event.setPing(builder.build());
}
@Override
public boolean isInvalidProtocol(){
return protocol == null;
}
@Override
public int getProtocolVersion(){
return protocol.getProtocol();
}
@Override
public int getOnlinePlayers(){
return builder.getOnlinePlayers();
}
@Override
public int getMaxPlayers(){
return builder.getMaximumPlayers();
}
@Override
public String getPlayerIP(){
return event.getConnection().getRemoteAddress().getHostString();
}
@Override
public String parsePAPIPlaceholders(String text, GenericPlayer<Player> player){
return text;
}
@Override
public String getVirtualHost(){
return this.resolveHost(event.getConnection().getVirtualHost().orElse(null));
}
@Override
public PluginCore<Favicon> getPlugin(){
return plugin;
}
@Override
public GenericPlayer<Player> createPlayer(CachedPlayer player, int protocol){
return new VelocityPlayer(player, protocol);
}
@Override
public Favicon createFavicon(BufferedImage image){
return Favicon.create(image);
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
* 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
@@ -50,4 +50,9 @@ public class VelocityLogger implements PluginLogger{
public void warn(String msg, Throwable throwable){
logger.warn(msg, throwable);
}
@Override
public void warn(String msg, Throwable throwable, Object... args){
logger.warn(String.format(msg, args), throwable);
}
}