Compare commits

...
355 Commits
Author SHA1 Message Date
Andre601 1ff439fa95 Use Java's HttpClient for update checks 2024-01-29 16:37:49 +01:00
Andre601 ed0f832b2f Merge pull request 'Update dependency mkdocs-material to v9.5.6' (#217) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/217
2024-01-28 12:02:57 +00:00
Andre601's Renovate Bot b8e6b2acc6 Update dependency mkdocs-material to v9.5.6 2024-01-28 12:01:18 +00:00
Andre601 fba32c91c5 Add page about expressions 2024-01-28 00:20:52 +01:00
Andre601 6505ded12b Use assertEquals(...) for testing 2024-01-27 23:25:17 +01:00
Andre601 53088affcb docs/profiles/index.md aktualisiert 2024-01-27 22:23:00 +00:00
Andre601 9c030764fa Merge pull request 'Update dependency mkdocs-glightbox to v0.3.7' (#215) from renovate/mkdocs-glightbox-0.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/215
2024-01-25 12:06:08 +00:00
Andre601 d5d58f1eea Merge branch 'master' into renovate/mkdocs-glightbox-0.x 2024-01-25 12:05:53 +00:00
Andre601 7181092821 Merge pull request 'Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.3.1' (#216) from renovate/org.apache.httpcomponents.client5-httpclient5-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/216
2024-01-25 12:05:37 +00:00
Andre601's Renovate Bot fc5ee4f242 Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.3.1 2024-01-25 12:01:04 +00:00
Andre601's Renovate Bot 6e74c4fb14 Update dependency mkdocs-glightbox to v0.3.7 2024-01-25 12:00:59 +00:00
Andre601 f6a27342e6 Merge pull request 'Update dependency mkdocs-material to v9.5.5' (#214) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/214
2024-01-24 12:17:57 +00:00
Andre601's Renovate Bot 38b50df2c9 Update dependency mkdocs-material to v9.5.5 2024-01-24 12:00:49 +00:00
Andre601 db93816e55 Remove configurate relocation in Velocity 2024-01-23 15:40:49 +01:00
Andre601 244c2440fc Add migration for pre 3.7.0 files 2024-01-20 22:27:43 +01:00
Andre601 8e2c644669 Merge pull request 'Update dependency org.junit.jupiter:junit-jupiter-engine to v5.10.1' (#213) from renovate/org.junit.jupiter-junit-jupiter-engine-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/213
2024-01-20 12:04:27 +00:00
Andre601 a68809ab31 Merge pull request 'Update dependency net.md-5:bungeecord-api to v1.20-R0.2' (#212) from renovate/net.md-5-bungeecord-api-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/212
2024-01-20 12:03:07 +00:00
Andre601's Renovate Bot 4b4fd80abe Update dependency org.junit.jupiter:junit-jupiter-engine to v5.10.1 2024-01-20 12:01:07 +00:00
Andre601's Renovate Bot 48ea128267 Update dependency net.md-5:bungeecord-api to v1.20-R0.2 2024-01-20 12:01:00 +00:00
Andre601 68e5795618 Link to new condition option 2024-01-19 15:37:27 +00:00
Andre601 1aa20e4196 Bump version to 3.7.0-b1 2024-01-19 16:10:56 +01:00
Andre601 6db25c8f9c Merge pull request 'Use BungeeTabListPlus inspired Condition system' (#209) from feature/use-btlp-condition-system into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/209
2024-01-19 15:06:30 +00:00
Andre601 0ef3db752d Improve docs 2024-01-19 16:05:54 +01:00
Andre601 1a26f5ad34 Merge branch 'master' into feature/use-btlp-condition-system 2024-01-19 14:51:10 +00:00
Andre601 17a5574be7 Fix placeholder issue (I hope) 2024-01-18 22:33:36 +01:00
Andre601 c7bfb8a736 Update examples and bump version 2024-01-18 14:29:54 +01:00
Andre601 7a756c3b98 Merge pull request 'Update actions/cache action to v4' (#211) from renovate/actions-cache-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/211
2024-01-18 12:09:07 +00:00
Andre601's Renovate Bot 1539e1c3c0 Update actions/cache action to v4 2024-01-18 12:01:20 +00:00
Andre601 a86872c021 Remove unused applyStringToStringFunction 2024-01-17 16:53:07 +01:00
Andre601 7d12499f39 Update docs and add basic tests 2024-01-17 16:48:35 +01:00
Andre601 455434b5f3 Merge pull request 'Update dependency net.william278:papiproxybridge to v1.5' (#210) from renovate/net.william278-papiproxybridge-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/210
2024-01-17 12:02:54 +00:00
Andre601's Renovate Bot b66251ab20 Update dependency net.william278:papiproxybridge to v1.5 2024-01-17 12:01:18 +00:00
Andre601 4a1dfa5cb4 Use dedicated Template class for errors. 2024-01-16 22:58:06 +01:00
Andre601 1efd65e16c Merge branch 'master' into feature/use-btlp-condition-system 2024-01-16 21:48:26 +00:00
Andre601 908da9cd32 Add some logging messages 2024-01-16 22:47:53 +01:00
Andre601 e8a30c6ef7 Use BungeeTabListPlus inspired Condition system 2024-01-16 22:23:24 +01:00
Andre601 df164c104f Merge pull request 'Update dependency mkdocs-material to v9.5.4' (#208) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/208
2024-01-15 12:02:23 +00:00
Andre601's Renovate Bot acdf6f6e9a Update dependency mkdocs-material to v9.5.4 2024-01-15 12:01:07 +00:00
Andre601 f52a63a8f1 Merge pull request 'Update dependency mkdocs-glightbox to v0.3.6' (#207) from renovate/mkdocs-glightbox-0.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/207
2023-12-31 14:14:03 +00:00
Andre601's Renovate Bot 6a92cb3a16 Update dependency mkdocs-glightbox to v0.3.6 2023-12-31 12:01:29 +00:00
Andre601 1175451753 Merge pull request 'Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.12.1' (#206) from renovate/org.apache.maven.plugins-maven-compiler-plugin-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/206
2023-12-25 13:39:01 +00:00
Andre601's Renovate Bot 5c4130411b Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.12.1 2023-12-25 12:02:04 +00:00
Andre601 05727eeec5 Merge pull request 'Update dependency mkdocs-material to v9.5.3' (#205) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/205
2023-12-24 13:02:23 +00:00
Andre601's Renovate Bot 10af949abc Update dependency mkdocs-material to v9.5.3 2023-12-24 12:01:33 +00:00
Andre601 9851347e74 Merge pull request 'Update dependency net.kyori:adventure-platform-bungeecord to v4.3.2' (#204) from renovate/net.kyori-adventure-platform-bungeecord-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/204
2023-12-22 12:06:31 +00:00
Andre601's Renovate Bot c3e01c8b9c Update dependency net.kyori:adventure-platform-bungeecord to v4.3.2 2023-12-22 12:01:07 +00:00
Andre601 a646d9e998 Merge pull request 'Update dependency com.google.guava:guava to v33' (#203) from renovate/com.google.guava-guava-33.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/203
2023-12-21 12:06:31 +00:00
Andre601's Renovate Bot 3c50a30d4a Update dependency com.google.guava:guava to v33 2023-12-21 12:01:11 +00:00
Andre601 4328ad6b44 Merge pull request 'Update actions/upload-pages-artifact action to v3' (#202) from renovate/actions-upload-pages-artifact-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/202
2023-12-20 12:18:17 +00:00
Andre601 34b0555508 Merge pull request 'Update actions/deploy-pages action to v4' (#201) from renovate/actions-deploy-pages-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/201
2023-12-20 12:18:04 +00:00
Andre601's Renovate Bot c92cd0058b Update actions/upload-pages-artifact action to v3 2023-12-20 12:01:05 +00:00
Andre601's Renovate Bot 2cfe8b8a27 Update actions/deploy-pages action to v4 2023-12-20 12:01:01 +00:00
Andre601 6530fed704 Merge pull request 'Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.12.0' (#200) from renovate/org.apache.maven.plugins-maven-compiler-plugin-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/200
2023-12-19 12:05:46 +00:00
Andre601 7efb203e7b Merge branch 'master' into renovate/org.apache.maven.plugins-maven-compiler-plugin-3.x 2023-12-19 12:05:24 +00:00
Andre601 1a34376100 Merge pull request 'Update dependency net.kyori:adventure-text-serializer-legacy to v4.15.0' (#199) from renovate/net.kyori-adventure-text-serializer-legacy-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/199
2023-12-19 12:05:00 +00:00
Andre601's Renovate Bot ec1aa5b393 Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.12.0 2023-12-19 12:01:42 +00:00
Andre601's Renovate Bot 9683d3c001 Update dependency net.kyori:adventure-text-serializer-legacy to v4.15.0 2023-12-19 12:01:30 +00:00
Andre601 db60545fcc Add 1.20.4 in ModrinthVersionUploader 2023-12-18 20:19:44 +01:00
Andre601 392495ef63 Merge pull request 'Update dependency net.kyori:adventure-text-minimessage to v4.15.0' (#198) from renovate/net.kyori-adventure-text-minimessage-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/198
2023-12-18 12:53:37 +00:00
Andre601 903764b234 Merge branch 'master' into renovate/net.kyori-adventure-text-minimessage-4.x 2023-12-18 12:53:18 +00:00
Andre601 72329ed1e4 Merge pull request 'Update dependency net.kyori:adventure-api to v4.15.0' (#197) from renovate/net.kyori-adventure-api-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/197
2023-12-18 12:53:04 +00:00
Andre601's Renovate Bot c516b56053 Update dependency net.kyori:adventure-text-minimessage to v4.15.0 2023-12-18 12:44:29 +00:00
Andre601's Renovate Bot 5e4295fbfb Update dependency net.kyori:adventure-api to v4.15.0 2023-12-18 12:44:20 +00:00
Andre601 b140c0aa32 Merge pull request 'Add debug option for log messages' (#194) from feature/add-debug into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/194
2023-12-15 19:55:08 +00:00
Andre601 8f7b293541 Merge branch 'master' into feature/add-debug 2023-12-15 19:50:01 +00:00
Andre601 6f878164c5 Add debug option to getting started guide. 2023-12-13 18:27:17 +00:00
Andre601 a16801ff56 Remove mention of spigot being tested 2023-12-13 18:25:41 +00:00
Andre601 65a89cf762 Merge branch 'master' into feature/add-debug 2023-12-12 22:01:57 +00:00
Andre601 27d4ada179 Merge pull request 'Update maven Docker tag to v3.9.6' (#196) from renovate/maven-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/196
2023-12-12 12:03:23 +00:00
Andre601 574edfb246 Merge branch 'master' into renovate/maven-3.x 2023-12-12 12:03:04 +00:00
Andre601 7b7aad9d4e Merge pull request 'Update dependency mkdocs-material to v9.5.2' (#195) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/195
2023-12-12 12:02:38 +00:00
Andre601's Renovate Bot c5c9ed8109 Update maven Docker tag to v3.9.6 2023-12-12 12:01:19 +00:00
Andre601's Renovate Bot 58fea4090d Update dependency mkdocs-material to v9.5.2 2023-12-12 12:01:11 +00:00
Andre601 cd0aad6ec1 Add debug option for log messages 2023-12-09 20:26:54 +01:00
Andre601 fa45844434 Merge pull request 'Update dependency mkdocs-material to v9.5.1' (#192) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/192
2023-12-08 12:28:41 +00:00
Andre601 c4e2a144b5 Merge pull request 'Update actions/setup-python action to v5' (#193) from renovate/actions-setup-python-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/193
2023-12-08 12:28:31 +00:00
Andre601's Renovate Bot 7fe93c7021 Update actions/setup-python action to v5 2023-12-08 12:01:09 +00:00
Andre601's Renovate Bot 1d413a5c2a Update dependency mkdocs-material to v9.5.1 2023-12-08 12:01:00 +00:00
Andre601 51db52dbdd Merge pull request 'Update dependency com.viaversion:viaversion-api to v4.9.2' (#190) from renovate/com.viaversion-viaversion-api-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/190
2023-12-07 12:07:24 +00:00
Andre601 4ade528188 Merge pull request 'Update dependency mkdocs-material to v9.5.0' (#191) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/191
2023-12-07 12:07:12 +00:00
Andre601's Renovate Bot 64ba48a7c7 Update dependency mkdocs-material to v9.5.0 2023-12-07 12:02:54 +00:00
Andre601's Renovate Bot ac4edb2b97 Update dependency com.viaversion:viaversion-api to v4.9.2 2023-12-07 12:02:49 +00:00
Andre601 3ea000c98b Merge pull request 'Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.3' (#189) from renovate/org.apache.httpcomponents.client5-httpclient5-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/189
2023-12-06 13:06:15 +00:00
Andre601 746bef13e1 Merge pull request 'Update dependency com.viaversion:viaversion-api to v4.9.1' (#188) from renovate/com.viaversion-viaversion-api-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/188
2023-12-06 13:06:01 +00:00
Andre601's Renovate Bot 355ab73546 Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.3 2023-12-06 12:01:10 +00:00
Andre601's Renovate Bot 67170c70e0 Update dependency com.viaversion:viaversion-api to v4.9.1 2023-12-06 12:01:07 +00:00
Andre601 f99c2df4e8 Merge pull request 'Update actions/configure-pages action to v4' (#186) from renovate/actions-configure-pages-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/186
2023-12-05 12:12:05 +00:00
Andre601 212ec04fb8 Merge pull request 'Update actions/deploy-pages action to v3' (#187) from renovate/actions-deploy-pages-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/187
2023-12-05 12:11:49 +00:00
Andre601's Renovate Bot 89c6089101 Update actions/deploy-pages action to v3 2023-12-05 12:01:17 +00:00
Andre601's Renovate Bot 87bce39d9a Update actions/configure-pages action to v4 2023-12-05 12:01:12 +00:00
Andre601 18900547a0 Remove leading and trailing whitespaces from server names 2023-12-05 01:46:45 +01:00
Andre601 5df2e05a14 Fix wrong file paths for paper 2023-12-02 14:27:45 +01:00
Andre601 d4e4173cc3 Improve placeholders with world/server args 2023-12-02 13:59:56 +01:00
Andre601 562ad481c5 Bump version to 3.6.0 2023-12-02 12:43:11 +00:00
Andre601 a0ee2a4322 Merge pull request 'Remove Spigot support' (#183) from feature/remove-spigot-support into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/183
2023-12-02 12:42:30 +00:00
Andre601 2c92efdb43 Merge branch 'master' into feature/remove-spigot-support 2023-12-02 12:39:37 +00:00
Andre601 555dc9d6a5 Merge pull request 'Improve docs workflow setup' (#179) from feature/improve-docs-workflow into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/179
2023-12-02 12:39:28 +00:00
Andre601 27742c5e1b .woodpecker/publish_docs.yml aktualisiert 2023-12-02 12:39:16 +00:00
Andre601 280aeb8d2e Merge branch 'master' into feature/improve-docs-workflow 2023-12-02 12:38:49 +00:00
Andre601 92a868f0fa Merge pull request 'Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.2.3' (#185) from renovate/org.apache.httpcomponents.client5-httpclient5-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/185
2023-12-02 12:03:33 +00:00
Andre601 189ac5e09b Merge pull request 'Update dependency ch.qos.logback:logback-classic to v1.4.14' (#184) from renovate/ch.qos.logback-logback-classic-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/184
2023-12-02 12:03:13 +00:00
Andre601's Renovate Bot 833cb81d65 Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.2.3 2023-12-02 12:01:18 +00:00
Andre601's Renovate Bot ab09422da5 Update dependency ch.qos.logback:logback-classic to v1.4.14 2023-12-02 12:01:14 +00:00
Andre601 64cad6dc26 Remove Spigot from readme and docs 2023-12-01 17:00:14 +01:00
Andre601 ce78b493f4 Remove spigot from supported platforms in PlatformInfo 2023-12-01 16:58:43 +01:00
Andre601 c43048ea3f Remove Spigot support 2023-12-01 16:51:33 +01:00
Andre601 6d4d1600ab Add Getting Started page 2023-11-29 15:09:32 +01:00
Andre601 f114e99b9b Merge pull request 'Update dependency ch.qos.logback:logback-classic to v1.4.13' (#182) from renovate/ch.qos.logback-logback-classic-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/182
2023-11-29 12:06:26 +00:00
Andre601's Renovate Bot 3d587bc86d Update dependency ch.qos.logback:logback-classic to v1.4.13 2023-11-29 12:01:18 +00:00
Andre601 bd8c6be7c6 Merge pull request 'Update dependency ch.qos.logback:logback-classic to v1.4.12' (#181) from renovate/ch.qos.logback-logback-classic-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/181
2023-11-28 12:02:35 +00:00
Andre601's Renovate Bot b5d5d508e2 Update dependency ch.qos.logback:logback-classic to v1.4.12 2023-11-28 12:01:02 +00:00
Andre601 3001b65fe8 Merge pull request 'Update dependency mkdocs-material to v9.4.14' (#180) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/180
2023-11-27 12:08:29 +00:00
Andre601's Renovate Bot c82771db59 Update dependency mkdocs-material to v9.4.14 2023-11-27 12:01:59 +00:00
Andre601 9880836c25 Improve docs workflow setup 2023-11-25 00:32:57 +00:00
Andre601 f12ae28722 Add Source redirect for API 2023-11-25 00:19:59 +00:00
Andre601 42b0f0e94f Merge pull request 'Update dependency mkdocs-material to v9.4.12' (#178) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/178
2023-11-24 12:04:02 +00:00
Andre601's Renovate Bot 0a4b872051 Update dependency mkdocs-material to v9.4.12 2023-11-24 12:00:59 +00:00
Andre601 b1322105ed Merge pull request 'Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.2.2' (#177) from renovate/org.apache.httpcomponents.client5-httpclient5-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/177
2023-11-23 12:02:45 +00:00
Andre601 831ca57fbb Merge branch 'master' into renovate/org.apache.httpcomponents.client5-httpclient5-5.x 2023-11-23 12:02:17 +00:00
Andre601 6502639cd3 Merge pull request 'Update dependency mkdocs-material to v9.4.11' (#176) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/176
2023-11-23 12:01:54 +00:00
Andre601's Renovate Bot 5059b80db2 Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.2.2 2023-11-23 12:01:07 +00:00
Andre601's Renovate Bot ecdaf72963 Update dependency mkdocs-material to v9.4.11 2023-11-23 12:00:58 +00:00
Andre601 28e2ca69ed Merge pull request 'Update dependency mkdocs-material to v9.4.10' (#175) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/175
2023-11-19 20:40:20 +00:00
Andre601 9cad78b6e4 Merge branch 'master' into renovate/mkdocs-material-9.x 2023-11-19 21:39:40 +01:00
Andre601 af8654666b Merge pull request 'Update dependency mkdocs-glightbox to v0.3.5' (#174) from renovate/mkdocs-glightbox-0.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/174
2023-11-19 12:20:05 +00:00
Andre601's Renovate Bot 6cd474b35d Update dependency mkdocs-material to v9.4.10 2023-11-19 12:01:07 +00:00
Andre601's Renovate Bot 3802ab556c Update dependency mkdocs-glightbox to v0.3.5 2023-11-19 12:01:02 +00:00
Andre601 3a520eeaf0 Merge pull request 'Update dependency mkdocs-material to v9.4.9' (#173) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/173
2023-11-17 12:15:02 +00:00
Andre601's Renovate Bot 204f43c112 Update dependency mkdocs-material to v9.4.9 2023-11-17 12:00:45 +00:00
Andre601 fc8ed8e49e Merge pull request 'Update dependency mkdocs-material to v9.4.8' (#172) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/172
2023-11-06 12:02:13 +00:00
Andre601's Renovate Bot 56082c308b Update dependency mkdocs-material to v9.4.8 2023-11-06 12:01:06 +00:00
Andre601 205e563095 Fix wrong placeholder names. 2023-11-05 13:59:46 +00:00
Andre601 5b01940c60 Merge pull request 'Update dependency me.clip:placeholderapi to v2.11.5' (#171) from renovate/me.clip-placeholderapi-2.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/171
2023-10-29 12:05:36 +00:00
Andre601's Renovate Bot cbb087e3d1 Update dependency me.clip:placeholderapi to v2.11.5 2023-10-29 12:01:15 +00:00
Andre601 524b926244 Merge pull request 'Update dependency mkdocs-material to v9.4.7' (#170) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/170
2023-10-28 12:01:09 +00:00
Andre601's Renovate Bot 4059bbfe93 Update dependency mkdocs-material to v9.4.7 2023-10-28 12:00:43 +00:00
Andre601 9b0b69a4f4 Merge pull request 'Update maven Docker tag to v3.9.5' (#169) from renovate/maven-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/169
2023-10-20 12:02:12 +00:00
Andre601's Renovate Bot 10a82eb951 Update maven Docker tag to v3.9.5 2023-10-20 12:01:07 +00:00
Andre601 690f7dfaf0 Merge pull request 'Update dependency com.squareup.okhttp3:okhttp to v4.12.0' (#168) from renovate/com.squareup.okhttp3-okhttp-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/168
2023-10-17 12:03:39 +00:00
Andre601's Renovate Bot 6a22d20b3a Update dependency com.squareup.okhttp3:okhttp to v4.12.0 2023-10-17 12:00:59 +00:00
Andre601 b1072bb1fa Update HangarVersionUploader for latest API changes 2023-10-16 12:01:12 +02:00
Andre601 d20da91bab Remove Hangar for now 2023-10-16 11:43:54 +02:00
Andre601 17e9692028 Remove unused import 2023-10-16 11:22:37 +02:00
Andre601 45dc8a5fe6 Don't use closeable http client 2023-10-16 11:22:09 +02:00
Andre601 a237ac1ce4 Merge pull request 'Update dependency mkdocs-material to v9.4.6' (#167) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/167
2023-10-15 17:27:18 +00:00
Andre601's Renovate Bot 27e66a16b9 Update dependency mkdocs-material to v9.4.6 2023-10-15 17:01:04 +00:00
Andre601 8f98846bc3 Ignore deprecation state of getUnsafe() 2023-10-15 00:00:57 +02:00
Andre601 bbcab59845 Final change I hope 2023-10-14 23:59:49 +02:00
Andre601 3130e07070 More consistent names 2023-10-14 23:57:05 +02:00
Andre601 7bc61ddf4d Use more matching placeholder names 2023-10-14 23:54:32 +02:00
Andre601 53d15a9011 Bump version 2023-10-14 23:42:16 +02:00
Andre601 8718e4a0ae update PAPI placeholders info 2023-10-11 12:10:04 +00:00
Andre601 06a49956af Merge pull request 'Update dependency com.google.guava:guava to v32.1.3-jre' (#166) from renovate/com.google.guava-guava-32.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/166
2023-10-11 12:04:37 +00:00
Andre601's Renovate Bot 38ec131b69 Update dependency com.google.guava:guava to v32.1.3-jre 2023-10-11 12:00:57 +00:00
Andre601 1bdaa61dd9 Merge pull request 'Update dependency mkdocs-material to v9.4.5' (#165) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/165
2023-10-10 12:02:55 +00:00
Andre601's Renovate Bot 080d5055c4 Update dependency mkdocs-material to v9.4.5 2023-10-10 12:01:23 +00:00
Andre601 423b363964 Use maxPlayers value 2023-10-09 01:33:40 +02:00
Andre601 6b9abfccfc Update PlaceholderAPI placeholders 2023-10-07 12:53:46 +02:00
Andre601 f589a8da35 Update Docs 2023-10-06 23:54:51 +02:00
Andre601 465581306f docs/api/javadocs.md aktualisiert 2023-10-06 20:54:27 +00:00
Andre601 6b2919961b Merge pull request 'Add Javadoc redirect' (#164) from docs/javadoc-link into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/164
2023-10-06 20:52:04 +00:00
Andre601 adb6e797b2 Add Javadoc redirect 2023-10-06 20:51:35 +00:00
Andre601 b410b9438f Merge pull request 'Update dependency mkdocs-material to v9.4.4' (#163) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/163
2023-10-06 12:22:17 +00:00
Andre601's Renovate Bot c1d5b4efa9 Update dependency mkdocs-material to v9.4.4 2023-10-06 12:01:00 +00:00
Andre601 4785dd127e Only allow workflow_dispatch from now on 2023-10-04 14:19:16 +00:00
Andre601 9e8e2f7e74 Add missing id property 2023-10-03 21:49:01 +00:00
Andre601 c14dfe0f3a Merge pull request 'Update dependency com.viaversion:viaversion-api to v4.8.1' (#162) from renovate/com.viaversion-viaversion-api-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/162
2023-10-03 12:40:03 +00:00
Andre601's Renovate Bot ed92e7002c Update dependency com.viaversion:viaversion-api to v4.8.1 2023-10-03 12:01:05 +00:00
Andre601 8f93d9732c Merge pull request 'Update dependency mkdocs-material to v9.4.3' (#161) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/161
2023-10-02 12:03:50 +00:00
Andre601's Renovate Bot 96f8fa5860 Update dependency mkdocs-material to v9.4.3 2023-10-02 12:00:57 +00:00
Andre601 bfb857bd5c Merge pull request 'Update dependency net.william278:papiproxybridge to v1.4.2' (#160) from renovate/net.william278-papiproxybridge-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/160
2023-09-30 12:04:14 +00:00
Andre601 5fe3b5811c Merge pull request 'Update dependency net.kyori:adventure-platform-bungeecord to v4.3.1' (#159) from renovate/net.kyori-adventure-platform-bungeecord-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/159
2023-09-30 12:03:54 +00:00
Andre601's Renovate Bot 2a7eff0092 Update dependency net.william278:papiproxybridge to v1.4.2 2023-09-30 12:01:23 +00:00
Andre601 1907f5d47e Merge pull request 'Update dependency net.kyori:adventure-platform-bukkit to v4.3.1' (#158) from renovate/net.kyori-adventure-platform-bukkit-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/158
2023-09-29 12:03:12 +00:00
Andre601's Renovate Bot aa92350b52 Update dependency net.kyori:adventure-platform-bungeecord to v4.3.1 2023-09-29 12:01:05 +00:00
Andre601's Renovate Bot 869b9bd3b7 Update dependency net.kyori:adventure-platform-bukkit to v4.3.1 2023-09-29 12:00:56 +00:00
Andre601 fe31dcf0a4 Merge pull request 'Update dependency net.william278:papiproxybridge to v1.4.1' (#156) from renovate/net.william278-papiproxybridge-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/156
2023-09-26 18:39:12 +00:00
Andre601 6b44438f52 Use custom compact admonition boxes 2023-09-26 20:38:22 +02:00
Andre601's Renovate Bot 6b0c654f41 Update dependency net.william278:papiproxybridge to v1.4.1 2023-09-26 12:00:57 +00:00
Andre601 c28ff3a891 Use some JS to insert API version 2023-09-26 13:56:48 +02:00
Andre601 f424b41c3b Header consistency 2023-09-25 15:14:10 +02:00
Andre601 b5f901d8f5 Use Hangar version of PAPI as dependency 2023-09-25 15:04:10 +02:00
Andre601 29d52492fc Merge pull request 'Update dependency mkdocs-material to v9.4.2' (#155) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/155
2023-09-25 12:03:05 +00:00
Andre601's Renovate Bot 2d6af20bdc Update dependency mkdocs-material to v9.4.2 2023-09-25 12:01:00 +00:00
Andre601 59c913ecf8 Merge pull request 'Update dependency org.apache.maven.plugins:maven-shade-plugin to v3.5.1' (#154) from renovate/org.apache.maven.plugins-maven-shade-plugin-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/154
2023-09-24 22:18:35 +00:00
Andre601's Renovate Bot 4a50beb4e0 Update dependency org.apache.maven.plugins:maven-shade-plugin to v3.5.1 2023-09-24 22:16:36 +00:00
Andre601 c099127272 delete renovate.yml 2023-09-24 21:48:23 +00:00
Andre601 15974b5c54 Merge pull request 'Update dependency me.clip:placeholderapi to v2.11.4' (#153) from renovate/me.clip-placeholderapi-2.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/153
2023-09-24 13:03:36 +00:00
Andre601's Renovate Bot 483afe63c4 Update dependency me.clip:placeholderapi to v2.11.4 2023-09-24 12:00:56 +00:00
Andre601 f0cb458a34 Use snippets for API version display 2023-09-24 03:19:41 +02:00
Andre601 2c547cd6d0 Add changelog newline sanitization to HangarVersionUploader too 2023-09-23 22:35:45 +02:00
Andre601 e7282b4a97 Support all MC 1.19 versions. 2023-09-23 22:27:48 +02:00
Andre601 4fc0ad97fc Revert to normal publish setup 2023-09-23 21:59:12 +02:00
Andre601 3ae02167b9 Lowercase loaders 2023-09-23 21:55:49 +02:00
Andre601 e407b38565 Use proper plugin release to test. 2023-09-23 21:42:06 +02:00
Andre601 c98d52ed46 Make a dryrun-test for VersionUploader 2023-09-23 21:29:06 +02:00
Andre601 266913e4b4 Use response directly from client's execute method 2023-09-23 16:42:21 +02:00
Andre601 a3d4a009a5 Use unique ID for modrinth dependencies 2023-09-23 16:27:17 +02:00
Andre601 18e00d082e Use addLabels and not labels 2023-09-23 12:09:04 +00:00
Andre601 6a3979743b Merge pull request 'Update dependency mkdocs-material to v9.4.1' (#152) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/152
2023-09-23 12:05:45 +00:00
Andre601's Renovate Bot 3a29ad54ca Update dependency mkdocs-material to v9.4.1 2023-09-23 12:01:03 +00:00
Andre601 987c520160 Merge pull request 'Update dependency com.viaversion:viaversion-api to v4.8.0' (#151) from renovate/com.viaversion-viaversion-api-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/151
2023-09-22 12:06:48 +00:00
Andre601's Renovate Bot 4b6197f6e0 Update dependency com.viaversion:viaversion-api to v4.8.0 2023-09-22 12:00:55 +00:00
Andre601 01611d4130 Add 1.20.2 for ModrinthVersionUploader 2023-09-21 20:59:35 +02:00
Andre601 531aa65fcc Merge pull request 'Bump mkdocs-material to 9.4.0' (#150) from feature/update-mkdocs into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/150
2023-09-21 17:39:22 +00:00
Andre601 fb101c4a14 Use new emoji extension 2023-09-21 17:39:11 +00:00
Andre601 7bd97f5f5a Bump mkdocs-material to 9.4.0 2023-09-21 17:37:28 +00:00
Andre601 52c3edd0ea Use debug log level 2023-09-21 12:15:49 +00:00
Andre601 368e544051 Don't include core-module in codeberg release 2023-09-21 00:52:20 +02:00
Andre601 12b2f5a208 Give non-successful response codes on fails 2023-09-21 00:50:26 +02:00
Andre601 adc88a8640 Increase timeout delay for Release data fetching 2023-09-21 00:43:08 +02:00
Andre601 817db44492 Add null check for codeberg release 2023-09-21 00:40:57 +02:00
Andre601 f74f7dfa6b Use CompletableFuture.join() for VersionUploader 2023-09-21 00:37:12 +02:00
Andre601 e9c8730090 Merge pull request 'Fix docs' (#149) from fix/docs into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/149
2023-09-20 22:32:41 +00:00
Andre601 861ada0396 docs/examples/index.md aktualisiert 2023-09-20 22:32:29 +00:00
Andre601 a2fb9c3d81 Fix docs 2023-09-20 22:31:52 +00:00
Andre601 f747461018 Use the right Env variable... 2023-09-20 23:37:03 +02:00
Andre601 f408146d57 Fix wrong API URL. 2023-09-20 23:34:27 +02:00
Andre601 c684001fcf mkdocs.yml aktualisiert 2023-09-20 21:19:39 +00:00
Andre601 6dc53c8c4f define source and target for modrinth and hangar token 2023-09-20 21:17:24 +00:00
Andre601 64ab958c67 docs/examples/index.md aktualisiert 2023-09-20 20:20:26 +00:00
Andre601 7a66c9a0c9 Merge pull request 'Add maxPlayers options' (#145) from feature/maxplayers-option into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/145
2023-09-20 20:05:44 +00:00
Andre601 0ff658632a Merge branch 'master' into feature/maxplayers-option 2023-09-20 17:41:50 +00:00
Andre601 ee32347bd0 Merge pull request 'Re-make Modrinth and Hangar uploader' (#144) from feature/modrinth-and-hangar-uploader into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/144
2023-09-20 17:41:23 +00:00
Andre601 9e11038e98 Merge branch 'master' into feature/modrinth-and-hangar-uploader 2023-09-20 17:39:15 +00:00
Andre601 008ddbb98a .github/dependabot.yml gelöscht 2023-09-20 17:34:13 +00:00
Andre601 f084c17d76 Merge pull request 'Update api.version to v3.1.0' (#148) from renovate/api.version into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/148
2023-09-20 15:55:20 +00:00
Andre601's Renovate Bot 9dd73aec9d Update api.version to v3.1.0 2023-09-20 15:51:15 +00:00
Andre601 3ebf151f3a Improve renovate configuration 2023-09-20 11:50:28 +00:00
Andre601 872c194a62 Add 'folia-supported: true' to paper-plugin.yml 2023-09-20 11:03:19 +00:00
Andre601 d122603c70 Merge pull request 'Update dependency mkdocs-material to v9.3.2' (#146) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/146
2023-09-20 00:20:40 +00:00
Andre601's Renovate Bot 489fce2031 Update dependency mkdocs-material to v9.3.2 2023-09-20 00:06:48 +00:00
Andre601 1651151f26 Test without RENOVATE_ADD_LABELS for now 2023-09-19 23:49:21 +00:00
Andre601 aa61ea826f renovate.json aktualisiert 2023-09-19 23:48:42 +00:00
Andre601 0877eb4187 Add github token for release notes and gh actions dependencies 2023-09-19 23:43:49 +00:00
Andre601 6e89cdb3cc .woodpecker/test.yml gelöscht 2023-09-19 23:24:07 +00:00
Andre601 1eb0b30356 Improve source facts fetcher 2023-09-19 22:53:51 +02:00
Andre601 417f5dc5d0 Also include image 2023-09-19 21:02:42 +02:00
Andre601 01a73b9ea3 Bump plugin and API version 2023-09-19 20:54:02 +02:00
Andre601 c06788a55c Update API changelog 2023-09-19 20:45:09 +02:00
Andre601 fd924107bc Add maxPlayers option for server list profile 2023-09-19 20:32:05 +02:00
Andre601 dce90b91f0 .woodpecker/publish_assets.yml aktualisiert 2023-09-18 18:22:30 +00:00
Andre601 aa968b7d25 Add gitea release plugin 2023-09-18 16:01:47 +02:00
Andre601 137d089e4a Merge branch 'master' into feature/modrinth-and-hangar-uploader 2023-09-18 13:11:27 +00:00
Andre601 bfa27f92e1 Re-make Modrinth and Hangar uploader 2023-09-18 15:10:24 +02:00
Andre601 b405706b50 Merge pull request 'Update dependency org.apache.maven.plugins:maven-shade-plugin to v3.5.0' (#143) from renovate/org.apache.maven.plugins-maven-shade-plugin-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/143
2023-09-18 00:06:48 +00:00
Andre601's Renovate Bot 89f44d7bec Update dependency org.apache.maven.plugins:maven-shade-plugin to v3.5.0 2023-09-18 00:04:39 +00:00
Andre601 28e9b6ed96 .woodpecker/test.yml aktualisiert 2023-09-17 20:29:19 +00:00
Andre601 19b3eec401 .woodpecker/test.yml aktualisiert 2023-09-17 20:11:37 +00:00
Andre601 c712b3b715 .woodpecker/test.yml aktualisiert 2023-09-17 20:10:22 +00:00
Andre601 5c379c3b13 .woodpecker/test.yml aktualisiert 2023-09-17 20:09:29 +00:00
Andre601 f6f48708d9 .woodpecker/test.yml aktualisiert 2023-09-17 20:08:51 +00:00
Andre601 83890fa5cb .woodpecker/test.yml aktualisiert 2023-09-17 20:07:55 +00:00
Andre601 d7653a6a6f .woodpecker/test.yml aktualisiert 2023-09-17 20:02:43 +00:00
Andre601 676c4c8f1f .woodpecker/test.yml aktualisiert 2023-09-17 20:00:49 +00:00
Andre601 b66870c942 .woodpecker/test.yml aktualisiert 2023-09-17 19:56:23 +00:00
Andre601 af97a0dac2 Test out JSON creation 2023-09-17 19:56:01 +00:00
Andre601 d43ef090ef Use double quotes 2023-09-17 19:42:36 +00:00
Andre601 e7451ae567 .woodpecker/test.yml aktualisiert 2023-09-17 19:32:57 +00:00
Andre601 cf4f095624 Test user auth 2023-09-17 19:28:12 +00:00
Andre601 9280809ab0 .woodpecker/publish_assets.yml aktualisiert 2023-09-17 19:25:04 +00:00
Andre601 875ae4d43d .woodpecker/test.yml aktualisiert 2023-09-17 19:19:27 +00:00
Andre601 dbd45ac65e .woodpecker/test.yml aktualisiert 2023-09-17 19:14:57 +00:00
Andre601 7c15778ebc test without token 2023-09-17 19:12:24 +00:00
Andre601 2699856a75 .woodpecker/test.yml aktualisiert 2023-09-17 19:11:30 +00:00
Andre601 b49c105620 .woodpecker/test.yml aktualisiert 2023-09-17 18:57:19 +00:00
Andre601 2ffbfeec48 .woodpecker/test.yml aktualisiert 2023-09-17 18:56:50 +00:00
Andre601 bd885e25e2 .woodpecker/test.yml aktualisiert 2023-09-17 18:56:11 +00:00
Andre601 e2c6eb142c Merge pull request 'Update dependency org.apache.maven.plugins:maven-jar-plugin to v3.3.0' (#142) from renovate/org.apache.maven.plugins-maven-jar-plugin-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/142
2023-09-17 00:12:53 +00:00
Andre601 db11e42c6d Merge pull request 'Update dependency net.md-5:bungeecord-api to v1.20-R0.1' (#141) from renovate/net.md-5-bungeecord-api-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/141
2023-09-17 00:12:11 +00:00
Andre601's Renovate Bot 36e5829943 Update dependency org.apache.maven.plugins:maven-jar-plugin to v3.3.0 2023-09-17 00:11:49 +00:00
Andre601's Renovate Bot 7bbb2bbfa7 Update dependency net.md-5:bungeecord-api to v1.20-R0.1 2023-09-17 00:11:46 +00:00
Andre601 6acd536f43 Merge pull request 'Update dependency net.kyori:adventure-text-minimessage to v4.14.0' (#140) from renovate/net.kyori-adventure-text-minimessage-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/140
2023-09-16 00:10:40 +00:00
Andre601 64d1440ad2 Merge pull request 'Update dependency net.kyori:adventure-platform-bungeecord to v4.3.0' (#139) from renovate/net.kyori-adventure-platform-bungeecord-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/139
2023-09-16 00:10:08 +00:00
Andre601's Renovate Bot 6f1dd78aa7 Update dependency net.kyori:adventure-text-minimessage to v4.14.0 2023-09-16 00:04:39 +00:00
Andre601's Renovate Bot 4330978816 Update dependency net.kyori:adventure-platform-bungeecord to v4.3.0 2023-09-16 00:04:22 +00:00
Andre601 935603b852 Use VersionUploader for hangar only again 2023-09-15 21:42:35 +02:00
Andre601 9671938a66 .woodpecker/test.yml aktualisiert 2023-09-15 19:16:23 +00:00
Andre601 5cc974eb9c Return of the | . 2023-09-15 19:15:44 +00:00
Andre601 e526cc6750 .woodpecker/test.yml aktualisiert 2023-09-15 19:09:20 +00:00
Andre601 34fea78b01 Check if tag actually is set. 2023-09-15 19:02:26 +00:00
Andre601 072547005c .woodpecker/test.yml aktualisiert 2023-09-15 19:01:39 +00:00
Andre601 cdb5852e8b .woodpecker/test.yml aktualisiert 2023-09-15 18:59:06 +00:00
Andre601 050477c19f .woodpecker/test.yml aktualisiert 2023-09-15 18:58:22 +00:00
Andre601 52b24bb3e9 .woodpecker/test.yml aktualisiert 2023-09-15 18:55:28 +00:00
Andre601 df8a063369 .woodpecker/test.yml aktualisiert 2023-09-15 18:48:48 +00:00
Andre601 3fc4a788b8 Add missing \ 2023-09-15 18:36:28 +00:00
Andre601 15e5108ec7 Try without {} again 2023-09-15 18:35:33 +00:00
Andre601 b8fa694e26 .woodpecker/test.yml aktualisiert 2023-09-15 18:32:19 +00:00
Andre601 f1b55cba79 try without auth 2023-09-15 18:30:11 +00:00
Andre601 e76dd78cd5 Try "${token}" format again 2023-09-15 18:28:42 +00:00
Andre601 09a668493b try this 2023-09-15 18:27:50 +00:00
Andre601 1ef466d2a4 Try single quotes 2023-09-15 18:19:51 +00:00
Andre601 e15ddbf2d4 Try this format? 2023-09-15 18:16:24 +00:00
Andre601 1c0ce073e5 Try "| ." again 2023-09-15 18:14:24 +00:00
Andre601 5964be18ed .woodpecker/test.yml aktualisiert 2023-09-15 18:13:11 +00:00
Andre601 06ad4f106b Try former select syntax 2023-09-15 18:12:05 +00:00
Andre601 adf343468f try --anyauth 2023-09-15 18:10:06 +00:00
Andre601 5a0bb3ce03 Try this structure 2023-09-15 16:14:23 +00:00
Andre601 b3edb2833e Create test for curl setu 2023-09-15 16:12:04 +00:00
Andre601 83c2017544 .woodpecker/publish_assets.yml aktualisiert 2023-09-15 11:46:45 +00:00
Andre601 42ecf8ec2a Create github release creation step 2023-09-15 11:41:28 +00:00
Andre601 fe53c28f77 Re-add release workflow 2023-09-15 11:33:36 +00:00
Andre601 44e8b395f5 .woodpecker/renovate.yml aktualisiert 2023-09-15 00:12:47 +00:00
Andre601 13828897a2 Merge pull request 'Update dependency net.kyori:adventure-api to v4.14.0' (#138) from renovate/net.kyori-adventure-api-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/138
2023-09-15 00:08:18 +00:00
Andre601 965a9898ca Merge pull request 'Update dependency dev.masecla:Modrinth4J to v2.2.0' (#137) from renovate/dev.masecla-modrinth4j-2.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/137
2023-09-15 00:07:49 +00:00
Andre601's Renovate Bot d3c9d1e7e2 Update dependency net.kyori:adventure-api to v4.14.0 2023-09-15 00:03:11 +00:00
Andre601's Renovate Bot ff3df14a90 Update dependency dev.masecla:Modrinth4J to v2.2.0 2023-09-15 00:03:08 +00:00
Andre601 374f477645 Merge pull request 'Update dependency com.squareup.okhttp3:okhttp to v4.11.0' (#136) from renovate/com.squareup.okhttp3-okhttp-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/136
2023-09-14 00:04:07 +00:00
Andre601 11bcbc7918 Merge branch 'master' into renovate/com.squareup.okhttp3-okhttp-4.x 2023-09-14 00:03:55 +00:00
Andre601 f91f77dba0 Merge pull request 'Update dependency com.comphenix.protocol:ProtocolLib to v5.1.0' (#135) from renovate/com.comphenix.protocol-protocollib-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/135
2023-09-14 00:03:36 +00:00
Andre601's Renovate Bot ac36bc7c6c Update dependency com.squareup.okhttp3:okhttp to v4.11.0 2023-09-14 00:03:14 +00:00
Andre601's Renovate Bot 184aa7cd83 Update dependency com.comphenix.protocol:ProtocolLib to v5.1.0 2023-09-14 00:02:08 +00:00
Andre601 e20a80b410 Merge pull request 'Update dependency org.bstats:bstats-bungeecord to v3.0.2' (#134) from renovate/org.bstats-bstats-bungeecord-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/134
2023-09-13 19:44:52 +00:00
Andre601 43f5cbdcf1 Merge branch 'master' into renovate/org.bstats-bstats-bungeecord-3.x 2023-09-13 19:44:43 +00:00
Andre601 7c8d6067f5 Merge pull request 'Update dependency ch.qos.logback:logback-classic to v1.4.11' (#133) from renovate/ch.qos.logback-logback-classic-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/133
2023-09-13 19:41:51 +00:00
Andre601 5500239146 Merge branch 'master' into renovate/ch.qos.logback-logback-classic-1.x 2023-09-13 19:38:23 +00:00
Andre601 62844f3111 renovate.json aktualisiert 2023-09-13 19:37:24 +00:00
Andre601 37df1c6376 .woodpecker/renovate.yml aktualisiert 2023-09-13 19:25:08 +00:00
Andre601 abe1dea027 Disable dryrun for now 2023-09-13 19:24:47 +00:00
Andre601 66500050fe .woodpecker/renovate.yml aktualisiert 2023-09-13 19:24:06 +00:00
Andre601's Renovate Bot 2bc2f11fb1 Update dependency org.bstats:bstats-bungeecord to v3.0.2 2023-09-13 19:22:01 +00:00
Andre601's Renovate Bot 4b88c78036 Update dependency ch.qos.logback:logback-classic to v1.4.11 2023-09-13 19:21:57 +00:00
Andre601 5a98301b7d Merge pull request 'Configure Renovate' (#132) from renovate/configure into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/132
2023-09-13 19:19:37 +00:00
Andre601's Renovate Bot 2cf7fd4ffc Add renovate.json 2023-09-13 19:16:06 +00:00
Andre601 83349e1c37 Include git author 2023-09-13 19:13:33 +00:00
Andre601 d928991ca5 Add chmod 2023-09-13 18:32:01 +00:00
Andre601 8b3cd0fcee Setup git configuration 2023-09-13 18:31:11 +00:00
Andre601 2afd7483df steps, not pipeline 2023-09-13 18:25:09 +00:00
Andre601 ae108d1bed indent fix 2023-09-13 18:24:40 +00:00
Andre601 37e343e92e Create renovate.yml 2023-09-13 18:24:02 +00:00
Andre601 8b01a12ef9 Add admonition box to inform of moved wiki 2023-09-13 00:29:24 +02:00
Andre601 91ea80fbde Update docs 2023-09-12 22:04:49 +02:00
Andre601 deec676180 Fix wrong platforms for papiproxybridge 2023-09-12 19:57:49 +00:00
Andre601 5fb22a505f typo 2023-09-12 19:07:04 +00:00
Andre601 539a1300d2 Don't use gh-pages branch 2023-09-12 19:00:48 +00:00
Andre601 915fe7b134 .github/workflows/release.yml gelöscht 2023-09-12 18:46:21 +00:00
Andre601 da393a66c1 .github/workflows/pr-comment.yml gelöscht 2023-09-12 18:46:17 +00:00
Andre601 6563b93721 .github/workflows/create-pr-artifact.yml gelöscht 2023-09-12 18:46:11 +00:00
Andre601 c8e51ab82e .woodpecker/push_to_github.yml gelöscht 2023-09-12 18:45:51 +00:00
Andre601 435fbe721d typo 2023-09-12 18:35:05 +00:00
Andre601 3677e90ad1 Try this aproach 2023-09-12 18:33:01 +00:00
Andre601 cd96a87028 Bump mkdocs-material to 9.3.1 2023-09-12 18:29:46 +00:00
Andre601 3b1e5244e4 Try this syntax for jq 2023-09-12 13:57:44 +00:00
Andre601 07a1baff36 Merge pull request 'Create setup for GitHub hosted docs' (#131) from feature/improve-github-hosted-docs into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/131
2023-09-12 12:49:07 +00:00
Andre601 c87f6d5a0d Merge branch 'master' into feature/improve-github-hosted-docs 2023-09-12 12:48:31 +00:00
Andre601 36f6c41059 Fix workflow not having any upstream 2023-09-12 12:48:17 +00:00
Andre601 fa0170fa16 Add env variable to github workflow 2023-09-12 12:47:02 +00:00
Andre601 c66936861f Wrap entire announce block in if check 2023-09-12 12:43:38 +00:00
Andre601 8933c39ce0 Create option for env 2023-09-12 12:42:44 +00:00
Andre601 34865b5bb8 Create setup for GitHub hosted docs 2023-09-12 12:38:31 +00:00
Andre601 271ebed7b6 Setup basic github -> Codeberg mirror 2023-09-12 12:31:56 +00:00
Andre601 08e7eca34f Remove the System.exit at end of Modrinth upload 2023-09-12 00:10:02 +02:00
Andre601 0162bcdaaf Change dependency declaration for Modrinth 2023-09-11 23:47:46 +02:00
Andre601 39e76862d5 Add log message for ModrinthVersionUploader 2023-09-11 23:37:09 +02:00
153 changed files with 6386 additions and 2434 deletions

No files matched your search

-50
View File
@@ -1,50 +0,0 @@
version: 2
updates:
- package-ecosystem: maven
directory: "/bungeecord"
schedule:
interval: daily
open-pull-requests-limit: 10
labels:
- 'Type: Update Dependency'
- 'Target: BungeeCord'
- package-ecosystem: maven
directory: "/core"
schedule:
interval: daily
open-pull-requests-limit: 10
labels:
- 'Type: Update Dependency'
- 'Target: Core'
- package-ecosystem: maven
directory: "/bukkit"
schedule:
interval: daily
open-pull-requests-limit: 10
labels:
- 'Type: Update Dependency'
- 'Target: Bukkit'
- package-ecosystem: maven
directory: "/velocity"
schedule:
interval: daily
open-pull-requests-limit: 10
labels:
- 'Type: Update Dependency'
- 'Target: Velocity'
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
labels:
- 'Type: Update Dependency'
- 'Target: GitHub Action'
- package-ecosystem: pip
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
labels:
- 'Type: Update Dependency'
- 'Target: MkDocs'
-100
View File
@@ -1,100 +0,0 @@
name: Create PR Artifacts
on:
pull_request_target:
types:
- opened
- reopened
- synchronize
branches:
- master
paths-ignore:
- '.github/**'
- 'docs/**'
- '.gitignore'
- 'LICENSE'
- 'README.md'
- 'mkdocs.yml'
- 'requirements.txt'
concurrency:
group: '${{ github.workflow }}-${{ github.head_ref }}'
cancel-in-progress: false
permissions:
issues: write
pull-requests: write
jobs:
buildArtifacts:
runs-on: ubuntu-latest
outputs:
comment_id: ${{ steps.comment.outputs.comment-id }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- name: Find Comment
uses: peter-evans/find-comment@v2
id: find-comment
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: '<!-- pr-build comment -->'
- name: Print Comment info
run: |
echo "Comment ID: ${{ steps.find-comment.outputs.comment-id }}"
echo "Comment Author: ${{ steps.find-comment.outputs.comment-author }}"
echo "Comment created at: ${{ steps.find-comment.outputs.comment-created-at }}"
- name: Post/Update Comment
uses: peter-evans/create-or-update-comment@v3
id: comment
with:
issue-number: ${{ github.event.pull_request.number }}
comment-id: ${{ steps.find-comment.outputs.comment-id }}
edit-mode: replace
body-path: .github/assets/pr-comments/building.md
- name: Set up JDK 1.16
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '16'
cache: 'maven'
- name: Obtain short Commit SHA
id: get-commit
run: 'echo "sha_short=$(git rev-parse --short ${{ github.event.pull_request.head.sha }})" >> $GITHUB_OUTPUT'
- name: Build Jar files
run: mvn clean install
env:
COMMIT_SHA: ${{ steps.get-commit.outputs.sha_short }}
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: AdvancedServerList-Artifacts
path: '*/target/AdvancedServerList-*.jar'
if-no-files-found: error
commentOnFail:
needs: [buildArtifacts]
if: failure()
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- name: Render Markdown Template
id: render
uses: chuhlomin/render-template@v1.7
with:
template: './.github/assets/pr-comments/failed.md'
vars: |
commit: ${{ github.event.pull_request.head.sha }}
logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
- name: Update Comment (Failure)
uses: peter-evans/create-or-update-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
comment-id: ${{ needs.buildArtifacts.outputs.comment_id }}
edit-mode: replace
body: ${{ steps.render.outputs.result }}
+28 -18
View File
@@ -2,28 +2,33 @@ name: 'Deploy Site (Push)'
on:
workflow_dispatch:
push:
paths:
- 'docs/**'
- 'mkdocs.yml'
- 'mkdocs-theme/**'
- 'requirements.txt'
branches:
- master
tags-ignore:
- '**'
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
env:
GITHUB_REPO_INSTANCE: true
jobs:
build:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.7
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Create/Get Cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
key: ${{ github.ref }}
path: .cache
@@ -31,9 +36,14 @@ jobs:
run: |
python -m pip install --upgrade pip setuptools
python -m pip install -r requirements.txt
- name: Set up Git
run: |
git config user.name "github-actions[bot]"
git config user.email "actions@github.com"
- name: Deploy Files
run: mkdocs gh-deploy --force
- name: Build docs
run: mkdocs build
- name: Configure GitHub Pages
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: 'site/'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
-99
View File
@@ -1,99 +0,0 @@
name: Comment on Pull request
on:
workflow_run:
types:
- completed
workflows:
- 'Create PR Artifacts'
permissions:
issues: write
pull-requests: write
jobs:
comment:
if: github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Get Artifact and Pull request info
env:
GITHUB_TOKEN: ${{ github.token }} # Needs to be set as env variable so that 'gh api' can be used.
WORKFLOW_RUN_EVENT_OBJ: ${{ toJSON(github.event.workflow_run) }}
OWNER: ${{ github.repository_owner }}
REPO: ${{ github.event.repository.name }}
run: |
PREVIOUS_JOB_ID=$(jq -r '.id' <<< "$WORKFLOW_RUN_EVENT_OBJ")
echo "Previous Job ID: $PREVIOUS_JOB_ID"
echo "PREVIOUS_JOB_ID=$PREVIOUS_JOB_ID" >> "$GITHUB_ENV"
SUITE_ID=$(jq -r '.check_suite_id' <<< "$WORKFLOW_RUN_EVENT_OBJ")
echo "Previous Suite ID: $SUITE_ID"
echo "SUITE_ID=$SUITE_ID" >> "$GITHUB_ENV"
ARTIFACT_ID=$(gh api "/repos/$OWNER/$REPO/actions/artifacts" \
--jq ".artifacts.[] |
select(.workflow_run.id==${PREVIOUS_JOB_ID}) |
select(.expired==false) |
.id")
echo "Artifact ID: $ARTIFACT_ID"
echo "ARTIFACT_ID=$ARTIFACT_ID" >> "$GITHUB_ENV"
ARTIFACT_EXPIRE_DATE=$(gh api "/repos/$OWNER/$REPO/actions/artifacts" \
--jq ".artifacts.[] |
select(.workflow_run.id==${PREVIOUS_JOB_ID}) |
select(.expired==false) |
.expires_at")
echo "Artifact Expire Date: $ARTIFACT_EXPIRE_DATE"
echo "ARTIFACT_EXPIRE_DATE=$ARTIFACT_EXPIRE_DATE" >> "$GITHUB_ENV"
PR_NUMBER=$(jq -r '.pull_requests[0].number' \
<<< "$WORKFLOW_RUN_EVENT_OBJ")
echo "Pull request Number: $PR_NUMBER"
echo "PR_NUMBER=$PR_NUMBER" >> "$GITHUB_ENV"
HEAD_SHA=$(jq -r '.pull_requests[0].head.sha' \
<<< "$WORKFLOW_RUN_EVENT_OBJ")
echo "Head SHA: $HEAD_SHA"
echo "HEAD_SHA=$HEAD_SHA" >> "$GITHUB_ENV"
- name: Find Comment
uses: peter-evans/find-comment@v2
id: find-comment
with:
issue-number: ${{ env.PR_NUMBER }}
comment-author: 'github-actions[bot]'
body-includes: '<!-- pr-build comment -->'
- name: Print Comment info
run: |
echo "Comment ID: ${{ steps.find-comment.outputs.comment-id }}"
echo "Comment Author: ${{ steps.find-comment.outputs.comment-author }}"
echo "Comment created at: ${{ steps.find-comment.outputs.comment-created-at }}"
- name: Render Markdown Template
id: render
uses: chuhlomin/render-template@v1.7
env:
JOB_PATH: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ env.PREVIOUS_JOB_ID }}"
ARTIFACT_URL: "https://nightly.link/${{ github.repository }}/suites/${{ env.SUITE_ID }}/artifacts/${{ env.ARTIFACT_ID }}"
ARTIFACT_EXPIRE_DATE: "${{ env.ARTIFACT_EXPIRE_DATE }}"
HEAD_SHA: "${{ env.HEAD_SHA }}"
with:
template: './.github/assets/pr-comments/success.md'
timezone: Europe/Zurich
vars: |
commit: ${{ env.HEAD_SHA }}
logs: ${{ env.JOB_PATH }}
download: ${{ env.ARTIFACT_URL }}
expire: ${{ env.ARTIFACT_EXPIRE_DATE }}
- name: Update Comment
uses: peter-evans/create-or-update-comment@v3
with:
issue-number: ${{ env.PR_NUMBER }}
comment-id: ${{ steps.find-comment.outputs.comment-id }}
edit-mode: replace
body: ${{ steps.render.outputs.result }}
-125
View File
@@ -1,125 +0,0 @@
#
# Big thank you to @Kir-Antipov for providing this workflow file.
# Check out his mc-publish action here: https://github.com/Kir-Antipov/mc-publish
#
name: Publish Assets
on:
release:
types:
- published
jobs:
buildJars:
runs-on: ubuntu-latest
outputs:
plugin_release: ${{ steps.github-release.outputs.PLUGIN_RELEASE }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Get Version from Release
id: github-release
run: |
version=$(echo ${{ github.event.release.tag_name }} | cut -d'v' -f2)
echo "PLUGIN_RELEASE=$version" >> $GITHUB_OUTPUT
- name: Set up JDK 1.16
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '16'
cache: 'maven'
- name: Build Jar files
run: mvn clean install
- name: Save All files
uses: actions/upload-artifact@v3
with:
name: asl-files
path: |
*/target/AdvancedServerList-*.jar
hangar-uploader/target/HangarUploader.jar
if-no-files-found: error
retention-days: 1
publish:
needs: [buildJars]
strategy:
matrix:
include:
- platforms: BungeeCord, Waterfall
directory: bungeecord
loaders: |
bungeecord
waterfall
dependencies: 'papiproxybridge@1.3(optional)'
- platforms: Spigot, Paper, Folia
directory: bukkit
loaders: |
spigot
paper
folia
dependencies: ''
- platforms: Velocity
directory: velocity
loaders: velocity
dependencies: 'papiproxybridge@1.3(optional)'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get Jar files
uses: actions/download-artifact@v3
with:
name: asl-files
- name: Upload AdvancedServerList v${{ needs.buildJars.outputs.plugin_release }} (${{ matrix.loaders }}) to GitHub and Modrinth
if: '!github.event.release.prerelease'
uses: Kir-Antipov/mc-publish@v3.3
with:
name: ${{ github.event.release.tag_name }} (${{ matrix.platforms }})
version: ${{ needs.buildJars.outputs.plugin_release }}
version-type: release
files: ${{ matrix.directory}}/target/AdvancedServerList-*.jar
loaders: ${{ matrix.loaders }}
game-version-filter: releases
game-versions: '>=1.19'
java: 16
dependencies: ${{ matrix.dependencies }}
modrinth-id: xss83sOY
modrinth-featured: false
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload AdvancedServerList v${{ needs.buildJars.outputs.plugin_release }} (${{ matrix.loaders }}) to GitHub and Modrinth [Pre-Release]
if: 'github.event.release.prerelease'
uses: Kir-Antipov/mc-publish@v3.3
with:
name: ${{ github.event.release.tag_name }} (${{ matrix.platforms }})
version: ${{ needs.buildJars.outputs.plugin_release }}
version-type: beta
files: ${{ matrix.directory }}/target/AdvancedServerList-*.jar
loaders: ${{ matrix.loaders }}
game-version-filter: releases
game-versions: '>=1.19'
java: 16
dependencies: ${{ matrix.dependencies }}
modrinth-id: xss83sOY
modrinth-featured: false
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
publishHangar:
needs: [buildJars]
runs-on: ubuntu-latest
steps:
- name: Set up JDK 1.16
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '16'
- name: Download Release Assets
uses: actions/download-artifact@v3
with:
name: asl-files
- name: Move HangarUploader.jar
working-directory: hangar-uploader/target/
run: mv HangarUploader.jar ../../
- name: Execute HangarUploader.jar
run: java -jar HangarUploader.jar ${{ secrets.HANGAR_TOKEN }} ${{ needs.buildJars.outputs.plugin_release }} ${{ github.event.release.prerelease }}
env:
GITHUB_RELEASE_BODY: ${{ github.event.release.body }}
+1
View File
@@ -2,3 +2,4 @@
/.idea/
/**/dependency-reduced-pom.xml
/**/target/
/**/__pycache__/
+20 -45
View File
@@ -4,55 +4,30 @@ when:
steps:
createFiles:
image: maven:3.9.4-eclipse-temurin-17
image: maven:3.9.6-eclipse-temurin-17
secrets:
- source: cb_token
target: codeberg_api_token
- source: modrinth_api_token
target: modrinth_api_token
- source: hangar_api_token
target: hangar_api_token
commands:
# Create the jar files.
- mvn clean install
#uploadFiles:
# image: badouralix/curl-jq
# secrets:
# - cb_token
# commands:
# # Get release info and setup env vars.
# - |-
# export JSON=`curl --location "https://codeberg.org/api/v1/repos/Andre601/AdvancedServerList/releases?limit=10" \
# --header 'Authorization: token $CB_TOKEN' \
# --header 'Accept: application/json' -s -S \
# --fail-with-body | jq ".[] | select (.tag_name==\"$CI_COMMIT_TAG\").")`
# - export PLUGIN_CHANGELOG=$( echo $JSON | jq -r '.body' )
# - export PLUGIN_PRE_RELEASE=$( echo $JSON | jq -r '.prerelease' )
# - export RELEASE_ID=$( echo $JSON | jq -r '.id' )
# # Upload release assets to Codeberg release
# - |-
# curl -X POST --location "https://codeberg.org/api/v1/repos/Andre601/AdvancedServerList/releases/$RELEASE_ID/assets" \
# --header "Authorization: token $CB_TOKEN" \
# --header "Content-Type: multipart/form-data" -s -S \
# --form "attachment=@bukkit/target/AdvancedServerList-Bukkit-${CI_COMMIT_TAG##v}.jar;type=application/octet-stream" \
# --fail-with-body
# - |-
# curl -X POST --location "https://codeberg.org/api/v1/repos/Andre601/AdvancedServerList/releases/$RELEASE_ID/assets" \
# --header "Authorization: token $CB_TOKEN" \
# --header "Content-Type: multipart/form-data" -s -S \
# --form "attachment=@bungeecord/target/AdvancedServerList-BungeeCord-${CI_COMMIT_TAG##v}.jar;type=application/octet-stream" \
# --fail-with-body
# - |-
# curl -X POST --location "https://codeberg.org/api/v1/repos/Andre601/AdvancedServerList/releases/$RELEASE_ID/assets" \
# --header "Authorization: token $CB_TOKEN" \
# --header "Content-Type: multipart/form-data" -s -S \
# --form "attachment=@velocity/target/AdvancedServerList-Velocity-${CI_COMMIT_TAG##v}.jar;type=application/octet-stream" \
# --fail-with-body
uploadToModrinthAndMaven:
image: eclipse-temurin
secrets:
- cb_token
- modrinth_api_token
- hangar_api_token
commands:
# Move VersionUploader.jar
# Move VersionUploader jar file
- cd version-uploader/target/
- mv VersionUploader.jar ../../
- cd ../../
# Create Modrinth releases
# Execute Jar file
- java -jar VersionUploader.jar --modrinth
# Create Hangar release
- java -jar VersionUploader.jar --hangar
uploadToCodeberg:
image: woodpeckerci/plugin-gitea-release
settings:
base_url: https://codeberg.org
files:
- "bungeecord/target/AdvancedServerList-*.jar"
- "paper/target/AdvancedServerList-*.jar"
- "velocity/target/AdvancedServerList-*.jar"
api_key:
from_secret: CB_TOKEN
+20 -12
View File
@@ -4,25 +4,33 @@ when:
path:
include: ['requirements.txt', 'mkdocs.yml', 'docs/**']
variables:
setup_git: &setup_git
- apk add git
- git config --global user.email "github@andre601.ch"
- git config --global user.name "ASL Docs Builder"
steps:
cloneTargetRepo:
image: alpine:3.18.4
commands:
- chmod -R a+w .
- <<: *setup_git
- git clone -b pages https://codeberg.org/Andre601/AdvancedServerList.git site
- chmod -R a+w site
buildDocs:
image: python
image: woodpeckerci/plugin-mkdocs:latest
settings:
pip_install_file: requirements.txt
commitAndPush:
image: alpine:3.18.4
secrets:
- cb_token
commands:
- chmod -R a+w .
- git config --global --add safe.directory /woodpecker/src/codeberg.org/Andre601/blog-source/website
- git config --global user.email "github@andre601.ch"
- git config --global user.name "CI Website Builder"
- git fetch --unshallow
- git clone -b pages https://codeberg.org/Andre601/AdvancedServerList.git site
- chmod -R a+w site
- python -m pip install --upgrade pip
- python -m pip install -r requirements.txt
- mkdocs build
- <<: *setup_git
- mv domains site/.domains
- cd site
- git remote set-url origin https://$CB_TOKEN@codeberg.org/Andre601/AdvancedServerList.git
- git add --all
- git commit -m "Update AdvancedServerList Docs ($( env TZ=Europe/Zurich date +"%d.%m.%Y" )) [CI SKIP]"
- git commit -m "Update AdvancedServerList Docs ($( env TZ=Europe/Zurich date +"%d.%m.%Y %Z" )) [SKIP CI]"
- git push
+16 -15
View File
@@ -3,19 +3,19 @@
AdvancedServerList is a plugin that allowys you to customize your server's MOTD, favicon, Player count text and player count hover displayed in a player's multiplayer server list based on conditions and priorities.
## Downloads
<a href="https://modrinth.com/plugin/advancedserverlist" target="_blank">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact/available/modrinth_vector.svg" height="46" alt="modrinth" title="Available on Modrinth">
</a>
<br>
<!--
<a href="https://hangar.papermc.io/Andre_601/AdvancedServerList" target="_blank">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact/available/hangar_vector.svg" height="46" alt="hangar" title="Available on Hangar">
</a>
-->
## Supported Platforms
<a href="https://www.spigotmc.org" target="_blank">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/supported/spigot_vector.svg" height="64" alt="platform-spigot" title="Tested on Spigot">
</a>
<a href="https://papermc.io" target="_blank">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/supported/paper_vector.svg" height="64" alt="platform-paper" title="Tested on Paper">
</a>
@@ -43,10 +43,10 @@ When multiple profiles exist that have valid conditions will the one with the hi
> [*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.
Placeholders can be used within conditions to further customize them. They can also be used in any other text option 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.
When using the SpigotMC/PaperMC version, or while PAPIProxyBridge is installed on your proxy, can you also use placeholders from [PlaceholderAPI][placeholderapi] using its `%<identifier>_<values>%` placeholder format. PlaceholderAPI needs to be installed for that.
If you're a plugin dev can you even add your own custom placeholders through AdvancedServerList's own API.
@@ -60,13 +60,14 @@ Only certain options are usable for each option. As an example does motd support
## Dependencies
| Dependency | Platforms | Required? |
|-------------------|-------------------------------------|-----------|
| [ProtocolLib] | Spigot | Yes |
| [PlaceholderAPI] | Spigot, Paper | No |
| [ViaVersion] | Spigot, Paper | No |
| [PAPIProxyBridge] | Spigot, Paper, BungeeCord, Velocity | No |
| [Maintenance] | Spigot, Paper, BungeeCord, Velocity | No |
All listed dependencies are optional.
| Dependency | Platforms |
|-------------------|----------------------|
| [PlaceholderAPI] | Paper |
| [ViaVersion] | Paper |
| [PAPIProxyBridge] | BungeeCord, Velocity |
| [Maintenance] | All |
## Statistics
@@ -84,6 +85,7 @@ You can disable this in the global bStats config file located in `/plugins/bstat
</a>
## Support
<a href="https://discord.gg/6dazXp6" target="_blank">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/social/discord-singular_vector.svg" height="64" alt="discord" title="Join my Discord Server">
</a>
@@ -96,14 +98,13 @@ You can disable this in the global bStats config file located in `/plugins/bstat
<!-- Links -->
[profiles]: https://asl.andre601.ch/profiles/
[conditions]: https://asl.andre601.ch/profiles/#conditions
[conditions]: https://asl.andre601.ch/profiles/#condition
[placeholders]: https://asl.andre601.ch/profiles/placeholders/
[minimessage]: https://asl.andre601.ch/profiles/formatting/
[modrinth]: https://modrinth.com/plugin/advancedserverlist
[protocollib]: https://hangar.papermc.io/dmulloy2/ProtocolLib
[placeholderapi]: https://www.spigotmc.org/resources/6245/
[placeholderapi]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
[viaversion]: https://hangar.papermc.io/ViaVersion/ViaVersion
[papiproxybridge]: https://hangar.papermc.io/William278/PAPIProxyBridge
[maintenance]: https://hangar.papermc.io/kennytv/Maintenance
@@ -1,75 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.bukkit.commands;
import ch.andre601.advancedserverlist.core.interfaces.commands.CmdSender;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.paper.commands.PaperCmdSender;
import ch.andre601.advancedserverlist.spigot.commands.SpigotCmdSender;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
public class CmdAdvancedServerList extends Command implements CommandExecutor{
private final PluginCore<?> plugin;
private final BukkitAudiences audiences;
public CmdAdvancedServerList(PluginCore<?> plugin){
this(plugin, null);
}
public CmdAdvancedServerList(PluginCore<?> plugin, BukkitAudiences audiences){
super(
"advancedserverlist",
"Main command of the plugin",
"/asl [reload|help|clearCache]",
Collections.singletonList("asl")
);
this.plugin = plugin;
this.audiences = audiences;
}
public boolean execute(@NotNull CommandSender sender, @NotNull String s, @NotNull String[] args){
plugin.getCore().getCommandHandler().handle(getSender(sender), args);
return true;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, @NotNull String[] args){
plugin.getCore().getCommandHandler().handle(getSender(sender), args);
return true;
}
private CmdSender getSender(CommandSender sender){
return audiences == null ? new PaperCmdSender(sender) : new SpigotCmdSender(sender, audiences);
}
}
@@ -1,74 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.bukkit.listeners;
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.PAPIPlaceholders;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import ch.andre601.advancedserverlist.spigot.listeners.ProtocolLibEvents;
import com.comphenix.protocol.ProtocolLibrary;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.ServerLoadEvent;
public class LoadEvent implements Listener{
private final BukkitCore<?> plugin;
private LoadEvent(BukkitCore<?> plugin){
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public static void init(BukkitCore<?> plugin){
new LoadEvent(plugin);
}
@EventHandler
public void onServerLoad(ServerLoadEvent event){
JoinEvent.init(plugin);
WorldEvents.init(plugin);
// Populate WorldCache with all loaded worlds
Bukkit.getWorlds().forEach(world -> plugin.getWorldCache().addWorld(world.getName(), world));
if(!(plugin instanceof SpigotCore spigotCore))
return;
if(!Bukkit.getPluginManager().isPluginEnabled("ProtocolLib")){
plugin.getCore().getPlugin().getPluginLogger().warn("ProtocolLib not found! AdvancedServerList requires it to work on Spigot!");
Bukkit.getPluginManager().disablePlugin(plugin);
return;
}
ProtocolLibEvents.init(spigotCore, ProtocolLibrary.getProtocolManager());
if(Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI"))
spigotCore.setPapiPlaceholders(PAPIPlaceholders.init(spigotCore));
}
}
@@ -1,62 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.bukkit.objects.placeholders;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.bukkit.objects.BukkitPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
public class BukkitPlayerPlaceholders extends PlaceholderProvider{
private BukkitPlayerPlaceholders(){
super("player");
}
public static BukkitPlayerPlaceholders init(){
return new BukkitPlayerPlaceholders();
}
@Override
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
if(!(player instanceof BukkitPlayer bukkitPlayer))
return null;
return switch(placeholder){
case "name" -> bukkitPlayer.getName();
case "protocol" -> String.valueOf(bukkitPlayer.getProtocol());
case "uuid" -> bukkitPlayer.getUUID().toString();
case "hasPlayedBefore" -> returnValue(bukkitPlayer, bukkitPlayer.hasPlayedBefore());
case "isBanned" -> returnValue(bukkitPlayer, bukkitPlayer.isBanned());
case "isWhitelisted" -> returnValue(bukkitPlayer, bukkitPlayer.isWhitelisted());
default -> null;
};
}
private String returnValue(BukkitPlayer player, Object value){
return player.getPlayer() == null ? null : String.valueOf(value);
}
}
@@ -1,61 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.paper;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import io.papermc.paper.plugin.loader.PluginClasspathBuilder;
import io.papermc.paper.plugin.loader.PluginLoader;
import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.repository.RemoteRepository;
import org.jetbrains.annotations.NotNull;
public class ASLLoader implements PluginLoader{
@Override
public void classloader(@NotNull PluginClasspathBuilder pluginClasspathBuilder){
ComponentLogger logger = pluginClasspathBuilder.getContext().getLogger();
logger.info(Component.text("Loading Libraries for plugin..."));
MavenLibraryResolver resolver = new MavenLibraryResolver();
resolver.addRepository(new RemoteRepository.Builder(
"paper-maven",
"default",
"https://repo.papermc.io/repository/maven-public/"
).build());
logger.info(Component.text("Loading com.squareup.okhttp3:okhttp:4.10.0 from repo.papermc.io..."));
resolver.addDependency(new Dependency(new DefaultArtifact("com.squareup.okhttp3:okhttp:4.10.0"), null));
pluginClasspathBuilder.addLibrary(resolver);
logger.info(Component.text("Loading libraries complete!"));
}
}
@@ -1,178 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.spigot;
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
import ch.andre601.advancedserverlist.bukkit.commands.CmdAdvancedServerList;
import ch.andre601.advancedserverlist.bukkit.logging.BukkitLogger;
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.BukkitPlayerPlaceholders;
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.BukkitServerPlaceholders;
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.PAPIPlaceholders;
import ch.andre601.advancedserverlist.bukkit.objects.WorldCache;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import ch.andre601.advancedserverlist.bukkit.listeners.LoadEvent;
import com.comphenix.protocol.wrappers.WrappedServerPing;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie;
import org.bukkit.command.PluginCommand;
import java.nio.file.Path;
public class SpigotCore extends BukkitCore<WrappedServerPing.CompressedImage>{
private final PluginLogger logger = new BukkitLogger(getLogger());
private AdvancedServerList<WrappedServerPing.CompressedImage> core;
private FaviconHandler<WrappedServerPing.CompressedImage> faviconHandler = null;
private PAPIPlaceholders<WrappedServerPing.CompressedImage> papiPlaceholders = null;
private WorldCache worldCache = null;
@Override
public void onEnable(){
try{
Class.forName("io.papermc.paper.configuration.ConfigurationLoaders");
printPaperInfo();
}catch(ClassNotFoundException ex){
try{
// Above class only exists since 1.19+, so this is a fallback for older versions.
Class.forName("com.destroystokyo.paper.PaperConfig");
printPaperInfo();
}catch(ClassNotFoundException ignored){}
}
this.core = AdvancedServerList.init(this, BukkitPlayerPlaceholders.init(), BukkitServerPlaceholders.init());
}
@Override
public void onDisable(){
if(papiPlaceholders != null){
papiPlaceholders.unregister();
papiPlaceholders = null;
}
if(worldCache != null)
worldCache = null;
getCore().disable();
}
@Override
public void loadCommands(){
PluginCommand cmd = getServer().getPluginCommand("advancedserverlist");
if(cmd == null){
getPluginLogger().warn("Unable to register command /advancedserverlist");
return;
}
cmd.setExecutor(new CmdAdvancedServerList(this, BukkitAudiences.create(this)));
}
@Override
public void loadEvents(){
LoadEvent.init(this);
}
@Override
public void loadMetrics(){
new Metrics(this, 15584).addCustomChart(new SimplePie("profiles",
() -> String.valueOf(core.getFileHandler().getProfiles().size())
));
}
@Override
public void clearFaviconCache(){
if(faviconHandler == null)
return;
faviconHandler.clearCache();
}
@Override
public AdvancedServerList<WrappedServerPing.CompressedImage> getCore(){
return core;
}
@Override
public Path getFolderPath(){
return getDataFolder().toPath();
}
@Override
public PluginLogger getPluginLogger(){
return logger;
}
@Override
public FaviconHandler<WrappedServerPing.CompressedImage> getFaviconHandler(){
if(faviconHandler == null)
faviconHandler = new FaviconHandler<>(core);
return faviconHandler;
}
@Override
public String getPlatformName(){
return getServer().getName();
}
@Override
public String getPlatformVersion(){
return getServer().getVersion();
}
@Override
public String getLoader(){
return "spigot";
}
@Override
public WorldCache getWorldCache(){
if(worldCache != null)
return worldCache;
return (worldCache = new WorldCache());
}
public void setPapiPlaceholders(PAPIPlaceholders<WrappedServerPing.CompressedImage> papiPlaceholders){
this.papiPlaceholders = papiPlaceholders;
}
private void printPaperInfo(){
getPluginLogger().warn("======================================================================================");
getPluginLogger().warn("You are using the Spigot version of AdvancedServerList on a Paper server.");
getPluginLogger().warn("It is recommended to use the dedicated Paper version, to benefit from the");
getPluginLogger().warn("following improvements:");
getPluginLogger().warn(" - No downloading of external Libraries already provided by Paper (i.e. Adventure).");
getPluginLogger().warn(" - No dependency on ProtocolLib thanks to provided Events.");
getPluginLogger().warn("");
getPluginLogger().warn("AdvancedServerList may work as normal, but consider using the PaperMC version instead!");
getPluginLogger().warn("======================================================================================");
}
}
@@ -1,203 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.spigot.listeners;
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
import ch.andre601.advancedserverlist.bukkit.listeners.PreServerListSetEventImpl;
import ch.andre601.advancedserverlist.bukkit.objects.impl.BukkitServerImpl;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import ch.andre601.advancedserverlist.bukkit.objects.impl.BukkitPlayerImpl;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedServerPing;
import me.clip.placeholderapi.PlaceholderAPI;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import java.awt.image.BufferedImage;
import java.util.*;
public class ProtocolLibEventWrapper implements GenericEventWrapper<WrappedServerPing.CompressedImage, BukkitPlayerImpl>{
private final SpigotCore plugin;
private final PacketEvent event;
private final WrappedServerPing ping;
public ProtocolLibEventWrapper(SpigotCore plugin, PacketEvent event){
this.plugin = plugin;
this.event = event;
this.ping = event.getPacket().getServerPings().read(0);
}
@Override
public GenericServerListEvent callEvent(ProfileEntry entry){
PreServerListSetEventImpl event = new PreServerListSetEventImpl(entry);
plugin.getServer().getPluginManager().callEvent(event);
return event;
}
@Override
public void setMaxPlayers(int maxPlayers){
ping.setPlayersMaximum(maxPlayers);
}
@Override
public void setMotd(Component component){
ping.setMotD(WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(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> lines, BukkitPlayerImpl player, GenericServer server){
List<WrappedGameProfile> players = new ArrayList<>(lines.size());
for(String line : lines){
String parsed = ComponentParser.text(line)
.modifyText(text -> StringReplacer.replace(text, player, server))
.modifyText(text -> {
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
return text;
})
.toString();
players.add(new WrappedGameProfile(UUID.randomUUID(), parsed));
}
ping.setPlayers(players);
}
@Override
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(){
event.getPacket().getServerPings().write(0, ping);
}
@Override
public boolean isInvalidProtocol(){
return event.getPlayer().getAddress() == null;
}
@Override
public boolean isMaintenanceModeActive(){
if(!Bukkit.getPluginManager().isPluginEnabled("Maintenance"))
return false;
return PingEventHandler.getMaintenanceUtil().isMaintenanceEnabled();
}
@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, BukkitPlayerImpl 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 ProtocolLibEvents.getHostAddresses().get(host);
}
@Override
public BukkitCore<WrappedServerPing.CompressedImage> getPlugin(){
return plugin;
}
@Override
public BukkitPlayerImpl createPlayer(CachedPlayer player, int protocol){
OfflinePlayer pl = Bukkit.getOfflinePlayer(player.getUuid());
return new BukkitPlayerImpl(pl.hasPlayedBefore() ? pl : null, player, protocol);
}
@Override
public GenericServer createGenericServer(int playersOnline, int playersMax, String host){
return new BukkitServerImpl(plugin.getWorldCache().worlds(), playersOnline, playersMax, host);
}
@Override
public WrappedServerPing.CompressedImage createFavicon(BufferedImage image) throws Exception{
return WrappedServerPing.CompressedImage.fromPng(image);
}
}
@@ -1,84 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.spigot.listeners;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
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 org.bukkit.Bukkit;
import org.bukkit.event.Listener;
import java.net.InetSocketAddress;
import java.util.Map;
import java.util.TreeMap;
public class ProtocolLibEvents implements Listener{
private final ProtocolManager protocolManager;
private static final Map<String, String> hostAddresses = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
private ProtocolLibEvents(SpigotCore plugin, ProtocolManager protocolManager){
this.protocolManager = protocolManager;
loadPacketListener(plugin);
Bukkit.getPluginManager().registerEvents(this, plugin);
}
public static void init(SpigotCore plugin, ProtocolManager protocolManager){
new ProtocolLibEvents(plugin, protocolManager);
}
public static Map<String, String> getHostAddresses(){
return hostAddresses;
}
private void loadPacketListener(SpigotCore spigotPlugin){
protocolManager.addPacketListener(new PacketAdapter(spigotPlugin, ListenerPriority.LOW, PacketType.Handshake.Client.SET_PROTOCOL){
@Override
public void onPacketReceiving(PacketEvent event){
InetSocketAddress address = event.getPlayer().getAddress();
if(address == null)
return;
String host = event.getPacket().getStrings().read(0);
hostAddresses.put(address.getHostString(), host);
}
});
protocolManager.addPacketListener(new PacketAdapter(spigotPlugin, ListenerPriority.LOW, PacketType.Status.Server.SERVER_INFO){
@Override
public void onPacketSending(PacketEvent event){
PingEventHandler.handleEvent(new ProtocolLibEventWrapper(spigotPlugin, event));
}
});
}
}
+8 -18
View File
@@ -67,39 +67,39 @@
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.19-R0.1-SNAPSHOT</version>
<version>1.20-R0.2</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.19-R0.1-SNAPSHOT</version>
<version>1.20-R0.2</version>
<type>javadoc</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.13.0</version>
<version>4.15.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.13.0</version>
<version>4.15.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-bungeecord</artifactId>
<version>4.1.2</version>
<version>4.3.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bungeecord</artifactId>
<version>3.0.0</version>
<version>3.0.2</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -108,12 +108,6 @@
<version>4.1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
@@ -128,12 +122,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<version>3.12.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
@@ -149,10 +143,6 @@
<pattern>org.bstats</pattern>
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>okhttp3</pattern>
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.okhttp3</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
@@ -46,7 +46,7 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
private AdvancedServerList<Favicon> core;
private FaviconHandler<Favicon> faviconHandler = null;
private final PluginLogger logger = new BungeeLogger(getLogger());
private final PluginLogger logger = new BungeeLogger(this);
@Override
public void onEnable(){
@@ -25,6 +25,7 @@
package ch.andre601.advancedserverlist.bungeecord.logging;
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import java.util.logging.Level;
@@ -32,10 +33,24 @@ import java.util.logging.Logger;
public class BungeeLogger implements PluginLogger{
private final BungeeCordCore plugin;
private final Logger logger;
public BungeeLogger(Logger logger){
this.logger = logger;
public BungeeLogger(BungeeCordCore plugin){
this.plugin = plugin;
this.logger = plugin.getLogger();
}
@Override
public void debug(Class<?> clazz, String msg, Object... args){
if(plugin.isDebugEnabled())
info("[DEBUG] [" + clazz.getSimpleName() + "] " + msg, args);
}
@Override
public void debugWarn(Class<?> clazz, String msg, Object... args){
if(plugin.isDebugEnabled())
warn("[DEBUG] [" + clazz.getSimpleName() + "] " + msg, args);
}
@Override
@@ -53,10 +53,14 @@ public class BungeeServerPlaceholders extends PlaceholderProvider{
return switch(args[0]){
case "playersOnline" -> {
if(args.length >= 2){
int players = 0;
String[] servers = args[1].split(",");
for(int i = 1; i < args.length; i++){
ServerInfo info = proxy.getServers().get(args[i]);
int players = 0;
for(String serverName : servers){
if(serverName.isEmpty())
continue;
ServerInfo info = proxy.getServers().get(serverName.strip());
if(info == null)
continue;
+15 -16
View File
@@ -41,6 +41,7 @@
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<plugin.config.version>3</plugin.config.version>
</properties>
<repositories>
@@ -71,22 +72,24 @@
<version>4.1.2</version>
<scope>provided</scope>
</dependency>
<!-- MiniMessage -->
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.14.0</version>
<version>4.15.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.14.0</version>
<version>4.15.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-legacy</artifactId>
<version>4.14.0</version>
<version>4.15.0</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -95,12 +98,6 @@
<version>2.10.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.11.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.unascribed</groupId>
<artifactId>flexver-java</artifactId>
@@ -110,13 +107,15 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.2-jre</version>
<version>33.0.0-jre</version>
<scope>provided</scope>
</dependency>
<!-- Plugins -->
<dependency>
<groupId>net.william278</groupId>
<artifactId>papiproxybridge</artifactId>
<version>1.3</version>
<version>1.5</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -128,9 +127,9 @@
<!-- Test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
</dependencies>
@@ -147,12 +146,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<version>3.12.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.0</version>
<version>3.5.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
@@ -31,7 +31,7 @@ import ch.andre601.advancedserverlist.core.check.UpdateChecker;
import ch.andre601.advancedserverlist.core.commands.CommandHandler;
import ch.andre601.advancedserverlist.core.file.FileHandler;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.objects.ServerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionEngine;
import ch.andre601.advancedserverlist.core.profiles.players.PlayerHandler;
import java.io.IOException;
@@ -48,6 +48,7 @@ public class AdvancedServerList<F>{
private final CommandHandler commandHandler;
private final PlayerHandler playerHandler;
private final AdvancedServerListAPI api = AdvancedServerListAPI.get();
private final ExpressionEngine expressionEngine = new ExpressionEngine();
private UpdateChecker updateChecker;
@@ -92,6 +93,10 @@ public class AdvancedServerList<F>{
return api;
}
public ExpressionEngine getExpressionEngine(){
return expressionEngine;
}
public void disable(){
getPlugin().getPluginLogger().info("Saving playercache.json file...");
getPlayerHandler().save();
@@ -137,7 +142,7 @@ public class AdvancedServerList<F>{
}
if(getFileHandler().loadProfiles()){
getPlugin().getPluginLogger().info("Successfully loaded " + getFileHandler().getProfiles().size() + " profiles!");
getPlugin().getPluginLogger().info("Successfully loaded %d profile(s)!", getFileHandler().getProfiles().size());
}else{
getPlugin().getPluginLogger().warn("Unable to load profiles! Check previous lines for errors.");
return;
@@ -30,18 +30,17 @@ 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.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -49,12 +48,10 @@ 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;
@SuppressWarnings("FieldCanBeLocal")
// 'https://api.modrinth.com/v2/project/advancedserverlist/version?loaders=["%s"]' URL encoded.
private final String url = "https://api.modrinth.com/v2/project/advancedserverlist/version?loaders=%%5B%%22%s%%22%%5D";
private final HttpClient client = HttpClient.newHttpClient();
private final Type listType = new TypeToken<ArrayList<ModrinthVersion>>(){}.getType();
private final Gson gson = new GsonBuilder()
@@ -65,6 +62,10 @@ public class UpdateChecker{
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new UpdateCheckThread());
private final AdvancedServerList<?> core;
private final PluginLogger logger;
private final String loader;
public UpdateChecker(AdvancedServerList<?> core){
this.core = core;
this.logger = core.getPlugin().getPluginLogger();
@@ -73,42 +74,13 @@ public class UpdateChecker{
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!");
logger.warn("Scheduler did not terminate in time!");
}
}catch(InterruptedException ex){
executor.shutdownNow();
@@ -116,108 +88,93 @@ public class UpdateChecker{
}
}
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;
}
private void startUpdateChecker(){
executor.scheduleAtFixedRate(() -> {
logger.info("Looking for an update...");
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;
performUpdateCheck().whenComplete((version, throwable) -> {
if(version == null || throwable != null){
logger.warn("Failed to look for any updates. Check previous messages for causes.");
return;
}
String responseString = body.string();
if(responseString.isEmpty()){
logger.warn("Received an empty Response body from Modrinth!");
return null;
logger.debug(UpdateChecker.class, "Comparing versions...");
int result = version.compare(core.getVersion());
switch(result){
case -1 -> printUpdateBanner(version);
case 0 -> logger.info("You are running the latest version!");
case 1 -> logger.info(
"Your version (%s) seems to be newer than the latest release (%s). Are you running a dev build?",
core.getVersion(), version.versionNumber()
);
}
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;
}
});
});
}, 0L, 12L, TimeUnit.HOURS);
}
private void printUpdateBanner(String version, String versionId, boolean isRelease){
private CompletableFuture<ModrinthVersion> performUpdateCheck(){
String finalUrl = String.format(url, loader);
logger.debug(UpdateChecker.class, "Checking '%s' for updates...", finalUrl);
if(core.getVersion().equals("UNKNOWN")){
logger.warn("Cannot perform update check. Plugin version is 'UNKNOWN'!");
return CompletableFuture.completedFuture(null);
}
HttpRequest request;
try{
request = HttpRequest.newBuilder()
.uri(new URI(finalUrl))
.header("User-Agent", "AdvancedServerList-" + loader + "/" + core.getVersion())
.build();
}catch(URISyntaxException ex){
logger.warn("Cannot perform update check. URL '%s' is not a valid URI.", ex, finalUrl);
return CompletableFuture.completedFuture(null);
}
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8))
.thenApply(response -> new ArrayList<ModrinthVersion>(gson.fromJson(response.body(), listType)))
.thenApply(list -> list.get(0))
.exceptionally((throwable) -> {
logger.warn("Encountered exception while performing update check!", throwable);
return null;
});
}
private void printUpdateBanner(ModrinthVersion version){
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("Modrinth: %s", version.versionNumber());
logger.info("");
if(!isRelease){
logger.info("WARNING: This release is an Alpha/Beta! It may contain");
logger.info(" breaking changes!");
if(!version.isRelease()){
logger.info("WARNING!");
logger.info("This is a %s version and may contain breaking changes and/or bugs!", version.versionType());
logger.info("");
}
logger.info("You can download the latest release from here:");
logger.info("https://modrinth.com/plugin/advancedserverlist/version/%s", versionId);
logger.info("Download the latest version from here:");
logger.info("https://modrinth.com/plugin/advancedserverlist/version/%s", version.id());
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 record ModrinthVersion(String id, String versionNumber, String versionType){
public boolean isRelease(){
return versionType.equals("release");
return versionType().equals("release");
}
public int compare(String version){
return FlexVerComparator.compare(version, versionNumber);
return FlexVerComparator.compare(version, versionNumber());
}
@Override
public String toString(){
return String.format("ModrinthVersion{id=%s,versionNumber=%s,versionType=%s}", id, versionNumber, versionType);
}
}
}
@@ -30,6 +30,7 @@ import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.core.compat.maintenance.MaintenanceUtil;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
import ch.andre601.advancedserverlist.core.compat.papi.PAPIUtil;
@@ -44,11 +45,17 @@ public class PingEventHandler{
private static MaintenanceUtil maintenanceUtil = null;
public static <F, P extends GenericPlayer> void handleEvent(GenericEventWrapper<F, P> event){
if(event.isInvalidProtocol() || event.isMaintenanceModeActive())
event.getPlugin().getPluginLogger().debug(PingEventHandler.class, "Received ping event. Handling it...");
if(event.isInvalidProtocol() || event.isMaintenanceModeActive()){
event.getPlugin().getPluginLogger().debug(PingEventHandler.class, "Not handling event. Either protocol was invalid of Maintenance is enabled.");
return;
}
PluginCore<F> plugin = event.getPlugin();
String host = event.getVirtualHost();
PluginLogger logger = plugin.getPluginLogger();
logger.debug(PingEventHandler.class, "Protocol valid. Continue handling...");
int online = event.getOnlinePlayers();
int max = event.getMaxPlayers();
@@ -61,25 +68,50 @@ public class PingEventHandler{
ServerListProfile profile = ProfileManager.resolveProfile(plugin.getCore(), player, server);
if(profile == null)
if(profile == null){
logger.debugWarn(PingEventHandler.class, "Server List Profile couldn't be resolved properly. Cancelling event handling...");
return;
}
logger.debug(PingEventHandler.class, "Received valid Server List Profile. Calling PreServerListSetEvent...");
GenericServerListEvent e = event.callEvent(ProfileManager.merge(profile));
if(e == null || e.isCancelled())
if(e == null || e.isCancelled()){
logger.debug(PingEventHandler.class, "PreServerListSetEvent was cancelled. Stopping ping handling...");
return;
}
logger.debug(PingEventHandler.class, "PreServerListSetEvent completed. Proceeding with ping handling...");
ProfileEntry entry = e.getEntry();
if(entry.isInvalid())
if(entry.isInvalid()){
logger.debugWarn(PingEventHandler.class, "No valid ProfileEntry retrieved. Cancelling ping handling...");
return;
}
if(ProfileManager.checkOption(entry.extraPlayersEnabled())){
boolean extraPlayers = ProfileManager.checkOption(entry.extraPlayersEnabled());
if(extraPlayers){
max = online + (entry.extraPlayersCount() == null ? 0 : entry.extraPlayersCount());
logger.debug(PingEventHandler.class, "Extra Players enabled. Applying '%d' as max player count...", max);
event.setMaxPlayers(max);
}
if(ProfileManager.checkOption(entry.maxPlayersEnabled()) && !extraPlayers){
max = (entry.maxPlayersCount() == null) ? 0 : entry.maxPlayersCount();
logger.debug(PingEventHandler.class, "Max Players enabled. Applying '%d' as max player count...", max);
event.setMaxPlayers(max);
}
GenericServer finalServer = event.createGenericServer(online, max, host);
if(ProfileManager.checkOption(entry.motd())){
logger.debug(PingEventHandler.class, "MOTD set. Applying '%s'...", String.join("\\n", entry.motd()));
event.setMotd(
ComponentParser.list(entry.motd())
.modifyText(text -> StringReplacer.replace(text, player, finalServer))
@@ -91,10 +123,14 @@ public class PingEventHandler{
boolean hidePlayers = ProfileManager.checkOption(entry.hidePlayersEnabled());
if(hidePlayers){
logger.debug(PingEventHandler.class, "Hide Players enabled. Hiding player count...");
event.hidePlayers();
}
if(ProfileManager.checkOption(entry.playerCountText()) && !hidePlayers){
logger.debug(PingEventHandler.class, "Player Count Text set. Applying '%s'...", entry.playerCountText());
event.setPlayerCount(
ComponentParser.text(entry.playerCountText())
.modifyText(text -> StringReplacer.replace(text, player, finalServer))
@@ -104,14 +140,19 @@ public class PingEventHandler{
}
if(ProfileManager.checkOption(entry.players()) && !hidePlayers){
logger.debug(PingEventHandler.class, "Player Count Hover set. Applying '%s'...", String.join("\\n", entry.players()));
event.setPlayers(entry.players(), player, server);
}
if(ProfileManager.checkOption(entry.favicon())){
logger.debug(PingEventHandler.class, "Favicon set. Resolving '%s'...", entry.favicon());
String favicon = StringReplacer.replace(entry.favicon(), player, server);
F fav = plugin.getFaviconHandler().getFavicon(favicon, image -> {
try{
logger.debug(PingEventHandler.class, "Converting BufferedImage to Server or Proxy Favicon instance...");
return event.createFavicon(image);
}catch(Exception ex){
plugin.getPluginLogger().warn("Encountered an Exception while creating Favicon!", ex);
@@ -120,12 +161,17 @@ public class PingEventHandler{
});
if(fav == null){
logger.debugWarn(PingEventHandler.class, "Favicon was invalid or not yet resolved! Using default favicon of Server/Proxy...");
event.setDefaultFavicon();
}else{
logger.debug(PingEventHandler.class, "Applying favicon...");
event.setFavicon(fav);
}
}
logger.debug(PingEventHandler.class, "Event handling completed. Updating Ping data...");
event.updateEvent();
}
@@ -25,6 +25,7 @@
package ch.andre601.advancedserverlist.core.file;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode;
@@ -32,16 +33,31 @@ import org.spongepowered.configurate.NodePath;
import org.spongepowered.configurate.transformation.ConfigurationTransformation;
import org.spongepowered.configurate.transformation.TransformAction;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ConfigMigrator{
public static final int LATEST = 1;
public static final int LATEST = resolveConfigVersion();
private ConfigMigrator(){}
public static ConfigurationTransformation.Versioned create(){
return ConfigurationTransformation.versionedBuilder()
.versionKey("configVersion")
.addVersion(LATEST, oneToTwo())
.addVersion(LATEST, twoToThree())
.addVersion(2, oneToTwo())
.build();
}
public static ConfigurationTransformation twoToThree(){
return ConfigurationTransformation.builder()
.addAction(NodePath.path(), ((path, value) -> {
value.node("debug").set(false);
return null;
}))
.build();
}
@@ -67,9 +83,21 @@ public class ConfigMigrator{
versioned.apply(node);
final int endVersion = versioned.version(node);
if(startVersion < endVersion)
logger.info("Migrated config.yml from " + startVersion + " to " + endVersion);
logger.info("Migrated config.yml from v" + startVersion + " to v" + endVersion);
}
return node;
}
private static int resolveConfigVersion(){
try(InputStream is = AdvancedServerList.class.getResourceAsStream("/version.properties")){
Properties properties = new Properties();
properties.load(is);
return Integer.parseInt(properties.getProperty("config-version"));
}catch(IOException | NumberFormatException ex){
return -1;
}
}
}
@@ -157,7 +157,7 @@ public class FileHandler{
continue;
profiles.add(ServerListProfile.Builder.resolve(file.getName(), tmp, logger).build());
logger.info("Loaded " + file.getName());
logger.info("Loaded '%s'!", file.getName());
}
if(profiles.isEmpty()){
@@ -178,7 +178,7 @@ public class FileHandler{
try{
return loader.load();
}catch(IOException ex){
logger.warn("Cannot load " + path.toFile().getName() + " due to an IOException!", ex);
logger.warn("Cannot load '%s' due to an IOException!", ex, path.toFile().getName());
return null;
}
}
@@ -214,7 +214,7 @@ public class FileHandler{
}
Files.copy(config, configBackup.toPath(), StandardCopyOption.REPLACE_EXISTING);
logger.info("Saved backup as '" + configBackup.getName() + "'!");
logger.info("Saved backup as '%s'!", configBackup.getName());
return true;
}catch(IOException ex){
@@ -27,6 +27,10 @@ package ch.andre601.advancedserverlist.core.interfaces;
public interface PluginLogger{
void debug(Class<?> clazz, String msg, Object... args);
void debugWarn(Class<?> clazz, String msg, Object... args);
void info(String msg, Object... args);
void warn(String msg, Object... args);
@@ -54,4 +54,8 @@ public interface PluginCore<F>{
String getPlatformVersion();
String getLoader();
default boolean isDebugEnabled(){
return getCore().getFileHandler().getBoolean("debug");
}
}
@@ -30,16 +30,22 @@ import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.conditions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionEngine;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionErrorTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.StringJoiner;
public class ServerListProfile{
private final int priority;
private final String condition;
private final List<Expression> expressions;
private final ProfileEntry defaultProfile;
@@ -47,8 +53,9 @@ public class ServerListProfile{
private final Random random = new Random();
public ServerListProfile(int priority, List<Expression> expressions, ProfileEntry defaultProfile, List<ProfileEntry> profiles){
public ServerListProfile(int priority, String condition, List<Expression> expressions, ProfileEntry defaultProfile, List<ProfileEntry> profiles){
this.priority = priority;
this.condition = condition;
this.expressions = expressions;
this.defaultProfile = defaultProfile;
@@ -59,7 +66,17 @@ public class ServerListProfile{
return priority;
}
public boolean evalConditions(GenericPlayer player, GenericServer server){
public boolean evalConditions(ExpressionEngine expressionEngine, PluginLogger logger, GenericPlayer player, GenericServer server){
if(condition != null && !condition.isEmpty()){
ExpressionTemplate template = expressionEngine.compile(condition, logger, player, server);
if(template instanceof ExpressionErrorTemplate errorTemplate){
logger.warn(errorTemplate.instantiateWithStringResult().evaluate());
return true;
}
return template.instantiateWithBooleanResult().evaluate();
}
if(expressions.isEmpty())
return true;
@@ -121,6 +138,7 @@ public class ServerListProfile{
private final PluginLogger logger;
private String condition = null;
private List<ProfileEntry> profiles = new ArrayList<>();
private ProfileEntry defaultProfile = ProfileEntry.empty();
@@ -133,11 +151,21 @@ public class ServerListProfile{
public static Builder resolve(String fileName, ConfigurationNode node, PluginLogger logger){
return new Builder(fileName, node, logger)
.resolveCondition()
.resolveExpressions()
.resolveProfiles()
.resolveDefaultProfile();
}
private Builder resolveCondition(){
String condition = node.node("condition").getString();
if(condition == null || condition.isEmpty())
return this;
this.condition = condition;
return this;
}
private Builder resolveExpressions(){
List<String> temp;
try{
@@ -150,6 +178,8 @@ public class ServerListProfile{
if(temp == null || temp.isEmpty())
return this;
StringJoiner joiner = new StringJoiner(" and ");
for(String str : temp){
Expression expr = Expression.resolve(str);
@@ -158,9 +188,18 @@ public class ServerListProfile{
continue;
}
joiner.add(str);
this.expressions.add(expr);
}
if(!this.expressions.isEmpty()){
logger.warn("'%s' uses 'conditions' which is deprecated in favour of the newer 'condition' option.", fileName);
logger.warn("The 'conditions' option will be removed in a future version.");
logger.warn("");
logger.warn("Please migrate your condition(s) over from the old option to the new option like this:");
logger.warn("consition: '%s'", joiner.toString());
}
return this;
}
@@ -184,7 +223,7 @@ public class ServerListProfile{
}
public ServerListProfile build(){
return new ServerListProfile(this.priority, this.expressions, this.defaultProfile, this.profiles);
return new ServerListProfile(this.priority, this.condition, this.expressions, this.defaultProfile, this.profiles);
}
}
}
@@ -0,0 +1,107 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.AbstractUnaryToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.AbstractUnaryToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.AbstractUnaryToStringExpression;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
public class Conversions{
private final static NumberFormat NUMBER_FORMAT;
static {
NUMBER_FORMAT = NumberFormat.getNumberInstance(Locale.ROOT);
NUMBER_FORMAT.setGroupingUsed(false);
}
public static ToBooleanExpression toBoolean(ToDoubleExpression expression){
return new AbstractUnaryToBooleanExpression<>(expression) {
@Override
public boolean evaluate(){
return delegate.evaluate() != 0;
}
};
}
public static ToBooleanExpression toBoolean(ToStringExpression expression){
return new AbstractUnaryToBooleanExpression<>(expression) {
@Override
public boolean evaluate(){
return Boolean.parseBoolean(delegate.evaluate());
}
};
}
public static ToDoubleExpression toDouble(ToBooleanExpression expression){
return new AbstractUnaryToDoubleExpression<>(expression) {
@Override
public double evaluate(){
return delegate.evaluate() ? 1 : 0;
}
};
}
public static ToDoubleExpression toDouble(ToStringExpression expression){
return new AbstractUnaryToDoubleExpression<>(expression) {
@Override
public double evaluate(){
String result = delegate.evaluate();
try{
return NUMBER_FORMAT.parse(result).doubleValue();
}catch(ParseException | NumberFormatException ex){
return 0;
}
}
};
}
public static ToStringExpression toString(ToBooleanExpression expression){
return new AbstractUnaryToStringExpression<>(expression) {
@Override
public String evaluate(){
return Boolean.toString(delegate.evaluate());
}
};
}
public static ToStringExpression toString(ToDoubleExpression expression){
return new AbstractUnaryToStringExpression<>(expression) {
@Override
public String evaluate(){
double result = delegate.evaluate();
return result == (int)result ? Integer.toString((int)result) : Double.toString(result);
}
};
}
}
@@ -0,0 +1,78 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers.TokenReader;
import com.google.common.collect.Ordering;
import java.text.ParsePosition;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class ExpressionTokenizer{
private static final Ordering<TokenReader> TOKEN_READER_ORDERING = Ordering.from(Comparator.comparingInt(TokenReader::getPriority)).reverse();
private final List<TokenReader> tokenReaders;
public ExpressionTokenizer(Iterable<TokenReader> tokenReaders){
this.tokenReaders = TOKEN_READER_ORDERING.immutableSortedCopy(tokenReaders);
}
public List<Token> parse(String text, PluginLogger logger, GenericPlayer player, GenericServer server){
ParsePosition position = new ParsePosition(0);
List<Token> tokens = new LinkedList<>();
next_token:
while(true){
while(position.getIndex() < text.length() && Character.isWhitespace(text.charAt(position.getIndex()))){
position.setIndex(position.getIndex() + 1);
}
if(position.getIndex() >= text.length())
break;
for(TokenReader tokenReader : tokenReaders){
Token token;
if(null != (token = tokenReader.read(text, position, player, server))){
tokens.add(token);
continue next_token;
}
}
logger.warn("Illegal token '%c' at index %d.", text.charAt(position.getIndex()), position.getIndex());
break;
}
return tokens;
}
}
@@ -0,0 +1,28 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.expressions;
public interface Expression{}
@@ -0,0 +1,170 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.expressions;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.conditions.ExpressionTokenizer;
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.ListOperator;
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.Operator;
import ch.andre601.advancedserverlist.core.profiles.conditions.parsers.*;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.BooleanToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.DefaultTokens;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers.*;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ExpressionEngine{
private final ExpressionTokenizer tokenizer;
private final ExpressionTemplateParser templateParser;
public ExpressionEngine(){
Options options = new Options.Builder()
.withDefaultTokenReaders()
.withDefaultOperators()
.withDefaultValueReaders()
.build();
this.tokenizer = new ExpressionTokenizer(options.tokenReaders);
this.templateParser = new ExpressionTemplateParser(options.operators, options.valueReaders);
}
public ExpressionTemplate compile(String expression, PluginLogger logger, GenericPlayer player, GenericServer server){
return templateParser.parse(tokenizer.parse(expression, logger, player, server));
}
public static class Options{
private final List<TokenReader> tokenReaders;
private final ImmutableMap<Token, Operator> operators;
private final ImmutableList<ValueReader> valueReaders;
private Options(List<TokenReader> tokenReaders, ImmutableMap<Token, Operator> operators, ImmutableList<ValueReader> valueReaders){
this.tokenReaders = tokenReaders;
this.operators = operators;
this.valueReaders = valueReaders;
}
public static class Builder{
private final List<TokenReader> tokenReaders = new ArrayList<>();
private final Map<Token, Operator> operators = new HashMap<>();
private final List<ValueReader> valueReaders = new ArrayList<>();
public Builder(){}
public Builder withDefaultTokenReaders(){
return this
.tokenReader(new PatternTokenReader(BooleanToken.FALSE, "false"))
.tokenReader(new PatternTokenReader(BooleanToken.TRUE, "true"))
.tokenReader(new PatternTokenReader(DefaultTokens.AND, "and"))
.tokenReader(new PatternTokenReader(DefaultTokens.AND, "&&"))
.tokenReader(new PatternTokenReader(DefaultTokens.OR, "or"))
.tokenReader(new PatternTokenReader(DefaultTokens.OR, "||"))
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL, "=="))
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL, "="))
.tokenReader(new PatternTokenReader(DefaultTokens.NOT_EQUAL, "!="))
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL_IGNORE_CASE, "~="))
.tokenReader(new PatternTokenReader(DefaultTokens.NOT_EQUAL_IGNORE_CASE, "!~"))
.tokenReader(new PatternTokenReader(DefaultTokens.GREATER_OR_EQUAL_THAN, ">="))
.tokenReader(new PatternTokenReader(DefaultTokens.LESSER_OR_EQUAL_THAN, "<="))
.tokenReader(new PatternTokenReader(DefaultTokens.OPENING_PARENTHESIS, "("))
.tokenReader(new PatternTokenReader(DefaultTokens.CLOSING_PARENTHESIS, ")"))
.tokenReader(new PatternTokenReader(DefaultTokens.NEGATION, "!"))
.tokenReader(new PatternTokenReader(DefaultTokens.GREATER_THAN, ">"))
.tokenReader(new PatternTokenReader(DefaultTokens.LESSER_THAN, "<"))
.tokenReader(new PatternTokenReader(DefaultTokens.CONCAT_STRING, "."))
.tokenReader(new PatternTokenReader(DefaultTokens.ADD, "+"))
.tokenReader(new PatternTokenReader(DefaultTokens.SUB, "-"))
.tokenReader(new PatternTokenReader(DefaultTokens.MULT, "*"))
.tokenReader(new PatternTokenReader(DefaultTokens.DIV, "/"))
.tokenReader(new QuotedLiteralTokenReader(-10, '\"'))
.tokenReader(new QuotedLiteralTokenReader(-10, '\''))
.tokenReader(new PlaceholderTokenReader(-20))
.tokenReader(new NumberTokenReader(-50))
.tokenReader(new NonQuotedLiteralTokenReader(-100));
}
public Builder withDefaultOperators(){
return this
.operator(DefaultTokens.AND, ListOperator.of(100, ExpressionTemplates::and))
.operator(DefaultTokens.OR, ListOperator.of(50, ExpressionTemplates::or))
.operator(DefaultTokens.EQUAL, Operator.of(25, ExpressionTemplates::equal))
.operator(DefaultTokens.NOT_EQUAL, Operator.of(25, ExpressionTemplates::notEqual))
.operator(DefaultTokens.EQUAL_IGNORE_CASE, Operator.of(25, ExpressionTemplates::equalIgnoreCase))
.operator(DefaultTokens.NOT_EQUAL_IGNORE_CASE, Operator.of(25, ExpressionTemplates::notEqualIgnoreCase))
.operator(DefaultTokens.GREATER_THAN, Operator.of(25, ExpressionTemplates::greater))
.operator(DefaultTokens.GREATER_OR_EQUAL_THAN, Operator.of(25, ExpressionTemplates::greaterOrEqual))
.operator(DefaultTokens.LESSER_THAN, Operator.of(25, ExpressionTemplates::less))
.operator(DefaultTokens.LESSER_OR_EQUAL_THAN, Operator.of(25, ExpressionTemplates::lessOrEqual))
.operator(DefaultTokens.CONCAT_STRING, ListOperator.of(10, ExpressionTemplates::concat))
.operator(DefaultTokens.ADD, ListOperator.of(4, ExpressionTemplates::sum))
.operator(DefaultTokens.SUB, Operator.of(3, ExpressionTemplates::sub))
.operator(DefaultTokens.MULT, ListOperator.of(2, ExpressionTemplates::product))
.operator(DefaultTokens.DIV, Operator.of(1, ExpressionTemplates::div));
}
public Builder withDefaultValueReaders(){
return this
.valueReader(new BooleanConstantReader())
.valueReader(new NumberConstantReader())
.valueReader(new StringConstantReader())
.valueReader(new NegatedExpressionReader(DefaultTokens.NEGATION))
.valueReader(new ParenthesisedExpressionReader(DefaultTokens.OPENING_PARENTHESIS, DefaultTokens.CLOSING_PARENTHESIS))
.valueReader(new PlaceholderReader())
.valueReader(new NegatedNumberReader(DefaultTokens.SUB));
}
public Builder tokenReader(TokenReader tokenReader){
this.tokenReaders.add(tokenReader);
return this;
}
public Builder operator(Token token, Operator operator){
this.operators.put(token, operator);
return this;
}
public Builder valueReader(ValueReader valueReader){
this.valueReaders.add(valueReader);
return this;
}
public Options build(){
return new Options(this.tokenReaders, ImmutableMap.copyOf(operators), ImmutableList.copyOf(valueReaders));
}
}
}
}
@@ -0,0 +1,211 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.expressions;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.*;
import java.util.Collection;
public class Expressions{
public static ToBooleanExpression negate(ToBooleanExpression expression){
return new AbstractUnaryToBooleanExpression<>(expression) {
@Override
public boolean evaluate(){
return !delegate.evaluate();
}
};
}
public static ToBooleanExpression and(Collection<ToBooleanExpression> operands){
return new AbstractToBooleanExpression<>(operands) {
@Override
public boolean evaluate(){
for(ToBooleanExpression operand : operands){
if(!operand.evaluate())
return false;
}
return true;
}
};
}
public static ToBooleanExpression or(Collection<ToBooleanExpression> operands){
return new AbstractToBooleanExpression<>(operands) {
@Override
public boolean evaluate(){
for(ToBooleanExpression operand : operands){
if(operand.evaluate())
return true;
}
return false;
}
};
}
public static ToStringExpression concat(Collection<ToStringExpression> operands){
return new AbstractToStringExpression<>(operands) {
@Override
public String evaluate(){
StringBuilder result = new StringBuilder();
for(ToStringExpression operand : operands){
result.append(operand.evaluate());
}
return result.toString();
}
};
}
public static ToBooleanExpression equal(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return a.evaluate().equals(b.evaluate());
}
};
}
public static ToBooleanExpression notEqual(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return !a.evaluate().equals(b.evaluate());
}
};
}
public static ToBooleanExpression equalIgnoreCase(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return a.evaluate().equalsIgnoreCase(b.evaluate());
}
};
}
public static ToBooleanExpression notEqualIgnoreCase(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return !a.evaluate().equalsIgnoreCase(b.evaluate());
}
};
}
public static ToBooleanExpression greaterThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return a.evaluate() > b.evaluate();
}
};
}
public static ToBooleanExpression greaterOrEqualThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return a.evaluate() >= b.evaluate();
}
};
}
public static ToBooleanExpression lessThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return a.evaluate() < b.evaluate();
}
};
}
public static ToBooleanExpression lessOrEqualThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return a.evaluate() <= b.evaluate();
}
};
}
public static ToDoubleExpression sum(Collection<ToDoubleExpression> operands){
return new AbstractToDoubleExpression<>(operands) {
@Override
public double evaluate(){
double result = 0;
for(ToDoubleExpression operand : operands){
result += operand.evaluate();
}
return result;
}
};
}
public static ToDoubleExpression product(Collection<ToDoubleExpression> operands){
return new AbstractToDoubleExpression<>(operands) {
@Override
public double evaluate(){
double result = 1;
for(ToDoubleExpression operand : operands){
result *= operand.evaluate();
}
return result;
}
};
}
public static ToDoubleExpression sub(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToDoubleExpression<>(a, b) {
@Override
public double evaluate(){
return a.evaluate() - b.evaluate();
}
};
}
public static ToDoubleExpression div(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToDoubleExpression<>(a, b) {
@Override
public double evaluate(){
return a.evaluate() / b.evaluate();
}
};
}
public static ToDoubleExpression negateNumber(ToDoubleExpression a){
return new AbstractUnaryToDoubleExpression<>(a) {
@Override
public double evaluate(){
return -delegate.evaluate();
}
};
}
}
@@ -0,0 +1,49 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.expressions;
public interface ToBooleanExpression extends Expression{
boolean evaluate();
static ToBooleanExpression literal(boolean value){
return new ConstantToBooleanExpression(value);
}
class ConstantToBooleanExpression implements ToBooleanExpression{
private final boolean value;
public ConstantToBooleanExpression(boolean value){
this.value = value;
}
@Override
public boolean evaluate(){
return value;
}
}
}
@@ -0,0 +1,49 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.expressions;
public interface ToDoubleExpression extends Expression{
double evaluate();
static ToDoubleExpression literal(double value){
return new ConstantToDoubleExpression(value);
}
class ConstantToDoubleExpression implements ToDoubleExpression{
private final double value;
public ConstantToDoubleExpression(double value){
this.value = value;
}
@Override
public double evaluate(){
return value;
}
}
}
@@ -0,0 +1,49 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.expressions;
public interface ToStringExpression extends Expression{
String evaluate();
static ToStringExpression literal(String value){
return new ConstantToStringExpression(value);
}
class ConstantToStringExpression implements ToStringExpression{
private final String value;
private ConstantToStringExpression(String value){
this.value = value;
}
@Override
public String evaluate(){
return value;
}
}
}
@@ -0,0 +1,56 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.operators;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
public abstract class ListOperator extends Operator{
public ListOperator(int priority){
super(priority);
}
public static ListOperator of(int priority, Function<Collection<ExpressionTemplate>, ExpressionTemplate> function){
return new ListOperator(priority){
@Override
public ExpressionTemplate createTemplate(List<ExpressionTemplate> operands){
return function.apply(operands);
}
};
}
@Override
public ExpressionTemplate createTemplate(ExpressionTemplate a, ExpressionTemplate b){
return createTemplate(Arrays.asList(a, b));
}
public abstract ExpressionTemplate createTemplate(List<ExpressionTemplate> operands);
}
@@ -0,0 +1,54 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.operators;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import java.util.function.BiFunction;
public abstract class Operator{
private final int priority;
public Operator(int priority){
this.priority = priority;
}
public static Operator of(int priority, BiFunction<ExpressionTemplate, ExpressionTemplate, ExpressionTemplate> function){
return new Operator(priority){
@Override
public ExpressionTemplate createTemplate(ExpressionTemplate a, ExpressionTemplate b){
return function.apply(a, b);
}
};
}
public int getPriority(){
return priority;
}
public abstract ExpressionTemplate createTemplate(ExpressionTemplate a, ExpressionTemplate b);
}
@@ -0,0 +1,44 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ConstantExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.BooleanToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.List;
public class BooleanConstantReader extends ValueReader{
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) instanceof BooleanToken){
return ConstantExpressionTemplate.of(((BooleanToken)tokenList.remove(0)).getValue());
}
return null;
}
}
@@ -0,0 +1,133 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.ListOperator;
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.Operator;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionErrorTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.List;
public class ExpressionTemplateParser{
private final ImmutableMap<Token, Operator> operators;
private final ImmutableList<ValueReader> valueReaders;
public ExpressionTemplateParser(ImmutableMap<Token, Operator> operators, ImmutableList<ValueReader> valueReaders){
this.operators = operators;
this.valueReaders = valueReaders;
}
public ExpressionTemplate parse(List<Token> tokenList){
List<ExpressionTemplate> parts = new ArrayList<>();
List<Operator> operators = new ArrayList<>();
try{
parts.add(read(tokenList));
}catch(IllegalArgumentException ex){
return ExpressionErrorTemplate.of(ex.getMessage());
}
while(!tokenList.isEmpty()){
Token token = tokenList.remove(0);
Operator operator = this.operators.get(token);
if(operator == null){
return ExpressionErrorTemplate.of("Error while parsing Expression. Got \"" + token + "\" but expected OPERATOR.");
}
operators.add(operator);
if(tokenList.isEmpty()){
return ExpressionErrorTemplate.of("Received unexpected end of input.");
}
try{
parts.add(read(tokenList));
}catch(IllegalArgumentException ex){
return ExpressionErrorTemplate.of(ex.getMessage());
}
}
while(!operators.isEmpty()){
Operator operator = operators.get(0);
int lowest = operator.getPriority();
int start = 0;
int end = 1;
for(int i = 1; i < operators.size(); i++){
operator = operators.get(i);
if(operator.getPriority() < lowest){
lowest = operator.getPriority();
start = i;
end = i + 1;
}else
if(operator.getPriority() > lowest){
break;
}else{
end++;
}
}
operator = operators.get(start);
ExpressionTemplate replacement;
if(start + 1 == end){
replacement = operator.createTemplate(parts.get(start), parts.get(end));
}else
if(operator instanceof ListOperator listOperator){
replacement = listOperator.createTemplate(new ArrayList<>(parts.subList(start, end + 1)));
}else{
List<ExpressionTemplate> conditions = new ArrayList<>(end - start);
for(int i = start; i < end; i++)
conditions.add(operators.get(i).createTemplate(parts.get(i), parts.get(i + 1)));
replacement = ExpressionTemplates.and(conditions);
}
for(int i = start; i < end; i++){
parts.remove(start);
operators.remove(start);
}
parts.set(start, replacement);
}
return parts.get(0);
}
ExpressionTemplate read(List<Token> tokenList){
for(ValueReader valueReader : valueReaders){
ExpressionTemplate template = valueReader.read(this, tokenList);
if(template != null)
return template;
}
throw new IllegalArgumentException("Invalid Expression. Expected literal but got token \"" + tokenList.get(0).toString() + "\"");
}
}
@@ -0,0 +1,51 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.List;
public class NegatedExpressionReader extends ValueReader{
private final Token tokenNegation;
public NegatedExpressionReader(Token tokenNegation){
this.tokenNegation = tokenNegation;
}
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) == tokenNegation){
tokenList.remove(0);
return ExpressionTemplates.negate(parser.read(tokenList));
}
return null;
}
}
@@ -0,0 +1,51 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.List;
public class NegatedNumberReader extends ValueReader{
private final Token tokenNegation;
public NegatedNumberReader(Token tokenNegation){
this.tokenNegation = tokenNegation;
}
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) == tokenNegation){
tokenList.remove(0);
return ExpressionTemplates.negateNumber(parser.read(tokenList));
}
return null;
}
}
@@ -0,0 +1,43 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ConstantExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.NumberToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.List;
public class NumberConstantReader extends ValueReader{
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) instanceof NumberToken){
return ConstantExpressionTemplate.of(((NumberToken)tokenList.remove(0)).getValue());
}
return null;
}
}
@@ -0,0 +1,71 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.ArrayList;
import java.util.List;
public class ParenthesisedExpressionReader extends ValueReader{
private final Token openingParenthesis;
private final Token closingParenthesis;
public ParenthesisedExpressionReader(Token openingParenthesis, Token closingParenthesis){
this.openingParenthesis = openingParenthesis;
this.closingParenthesis = closingParenthesis;
}
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) == openingParenthesis){
int index = 0;
int cnt = 1;
do {
index += 1;
if(tokenList.size() <= index)
return null;
Token token = tokenList.get(index);
if(token == openingParenthesis){
cnt++;
}else
if(token == closingParenthesis){
cnt--;
}
}while(cnt != 0);
ExpressionTemplate result = parser.parse(new ArrayList<>(tokenList.subList(1, index)));
tokenList.subList(0, index + 1).clear();
return result;
}
return null;
}
}
@@ -0,0 +1,43 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.PlaceholderToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.List;
public class PlaceholderReader extends ValueReader{
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) instanceof PlaceholderToken){
PlaceholderToken token = (PlaceholderToken)tokenList.remove(0);
return token.getValue();
}
return null;
}
}
@@ -0,0 +1,44 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ConstantExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.StringToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.List;
public class StringConstantReader extends ValueReader{
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) instanceof StringToken){
return ConstantExpressionTemplate.of(((StringToken)tokenList.remove(0)).getValue());
}
return null;
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
* Copyright (c) 2022-2024 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,17 +23,14 @@
*
*/
package ch.andre601.advancedserverlist.bukkit;
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
import ch.andre601.advancedserverlist.bukkit.objects.WorldCache;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import org.bukkit.plugin.java.JavaPlugin;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
/*
* Small convenience class to "merge" the PluginCore and JavaPlugin classes.
* Allows me to have BukkitCore<?> for whenever I also need a JavaPlugin (i.e. registering events).
* See JoinEvent class for an example.
*/
public abstract class BukkitCore<F> extends JavaPlugin implements PluginCore<F>{
public abstract WorldCache getWorldCache();
}
import java.util.List;
public abstract class ValueReader{
public abstract ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList);
}
@@ -0,0 +1,62 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.placeholders;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
public interface Placeholder extends ExpressionTemplate{
static LiteralPlaceholderValue of(String value){
return new LiteralPlaceholderValue(value);
}
class LiteralPlaceholderValue implements Placeholder{
private final String value;
public LiteralPlaceholderValue(String value){
this.value = value;
}
@Override
public ToStringExpression instantiateWithStringResult(){
return ToStringExpression.literal(value);
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return ToDoubleExpression.literal(value.length());
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return ToBooleanExpression.literal(Boolean.parseBoolean(value));
}
}
}
@@ -0,0 +1,111 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.placeholders;
import ch.andre601.advancedserverlist.api.AdvancedServerListAPI;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import java.text.ParsePosition;
public class PlaceholderParser{
public static Placeholder parse(String text, ParsePosition position, GenericPlayer player, GenericServer server){
AdvancedServerListAPI api = AdvancedServerListAPI.get();
int index = position.getIndex();
StringBuilder identifier = new StringBuilder();
StringBuilder values = new StringBuilder();
boolean identified = false;
boolean invalid = true;
char[] chars = text.substring(index).toCharArray();
for(final char c : chars){
index++;
if(c == '}'){
invalid = false;
break;
}
if(c == ' ' && !identified){
identified = true;
continue;
}
if(identified){
values.append(c);
}else{
identifier.append(c);
}
}
String identifierStr = identifier.toString();
String valuesStr = values.toString();
StringBuilder raw = new StringBuilder();
position.setIndex(index + 1);
if(invalid){
raw.append("${").append(identifierStr);
if(identified)
raw.append(' ').append(valuesStr);
return Placeholder.of(raw.toString());
}
PlaceholderProvider provider = api.retrievePlaceholderProvider(identifierStr);
if(provider == null){
raw.append("${").append(identifierStr);
if(identified)
raw.append(' ').append(valuesStr);
raw.append('}');
return Placeholder.of(raw.toString());
}
String replacement = provider.parsePlaceholder(valuesStr, player, server);
if(replacement == null){
raw.append("${").append(identifierStr);
if(identified)
raw.append(' ').append(valuesStr);
raw.append('}');
return Placeholder.of(raw.toString());
}
return Placeholder.of(replacement);
}
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
public abstract class AbstractBinaryToBooleanExpression<T extends Expression> implements ToBooleanExpression{
protected final T a;
protected final T b;
public AbstractBinaryToBooleanExpression(T a, T b){
this.a = a;
this.b = b;
}
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
public abstract class AbstractBinaryToDoubleExpression<T extends Expression> implements ToDoubleExpression{
protected final T a;
protected final T b;
public AbstractBinaryToDoubleExpression(T a, T b){
this.a = a;
this.b = b;
}
}
@@ -0,0 +1,43 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.Conversions;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
public abstract class AbstractBooleanExpressionTemplate implements ExpressionTemplate{
@Override
public ToStringExpression instantiateWithStringResult(){
return Conversions.toString(instantiateWithBooleanResult());
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Conversions.toDouble(instantiateWithBooleanResult());
}
}
@@ -0,0 +1,43 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.Conversions;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
public abstract class AbstractDoubleExpressionTemplate implements ExpressionTemplate{
@Override
public ToStringExpression instantiateWithStringResult(){
return Conversions.toString(instantiateWithDoubleResult());
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Conversions.toBoolean(instantiateWithDoubleResult());
}
}
@@ -0,0 +1,43 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.Conversions;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
public abstract class AbstractStringExpressionTemplate implements ExpressionTemplate{
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Conversions.toDouble(instantiateWithStringResult());
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Conversions.toBoolean(instantiateWithStringResult());
}
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import java.util.Collection;
public abstract class AbstractToBooleanExpression<T extends Expression> implements ToBooleanExpression{
protected final Collection<T> operands;
public AbstractToBooleanExpression(Collection<T> operands){
this.operands = operands;
}
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import java.util.Collection;
public abstract class AbstractToDoubleExpression<T extends Expression> implements ToDoubleExpression{
protected final Collection<T> operands;
public AbstractToDoubleExpression(Collection<T> operands){
this.operands = operands;
}
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
import java.util.Collection;
public abstract class AbstractToStringExpression<T extends Expression> implements ToStringExpression{
protected Collection<T> operands;
public AbstractToStringExpression(Collection<T> operands){
this.operands = operands;
}
}
@@ -0,0 +1,38 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
public abstract class AbstractUnaryToBooleanExpression<T extends Expression> implements ToBooleanExpression{
protected final T delegate;
public AbstractUnaryToBooleanExpression(T delegate){
this.delegate = delegate;
}
}
@@ -0,0 +1,38 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
public abstract class AbstractUnaryToDoubleExpression<T extends Expression> implements ToDoubleExpression{
protected final T delegate;
public AbstractUnaryToDoubleExpression(T delegate){
this.delegate = delegate;
}
}
@@ -0,0 +1,38 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
public abstract class AbstractUnaryToStringExpression<T extends Expression> implements ToStringExpression{
protected final T delegate;
public AbstractUnaryToStringExpression(T delegate){
this.delegate = delegate;
}
}
@@ -0,0 +1,77 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
public class ConstantExpressionTemplate implements ExpressionTemplate{
private final ToStringExpression stringExpression;
private final ToDoubleExpression doubleExpression;
private final ToBooleanExpression booleanExpression;
private ConstantExpressionTemplate(String stringValue, double doubleValue, boolean booleanValue){
this.stringExpression = ToStringExpression.literal(stringValue);
this.doubleExpression = ToDoubleExpression.literal(doubleValue);
this.booleanExpression = ToBooleanExpression.literal(booleanValue);
}
public static ConstantExpressionTemplate of(String stringValue){
double doubleValue;
try{
doubleValue = Double.parseDouble(stringValue);
}catch(NumberFormatException ex){
doubleValue = stringValue.length();
}
return new ConstantExpressionTemplate(stringValue, doubleValue, Boolean.parseBoolean(stringValue));
}
public static ConstantExpressionTemplate of(double doubleValue){
return new ConstantExpressionTemplate(((int)doubleValue) == doubleValue ? Integer.toString((int)doubleValue) : Double.toString(doubleValue), doubleValue, doubleValue != 0);
}
public static ConstantExpressionTemplate of(boolean booleanValue){
return new ConstantExpressionTemplate(Boolean.toString(booleanValue), booleanValue ? 1 : 0, booleanValue);
}
@Override
public ToStringExpression instantiateWithStringResult(){
return stringExpression;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return doubleExpression;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return booleanExpression;
}
}
@@ -0,0 +1,58 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
public class ExpressionErrorTemplate implements ExpressionTemplate{
private final String msg;
private ExpressionErrorTemplate(String msg){
this.msg = msg;
}
public static ExpressionErrorTemplate of(String msg){
return new ExpressionErrorTemplate(msg);
}
@Override
public ToStringExpression instantiateWithStringResult(){
return ToStringExpression.literal(msg);
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return ToDoubleExpression.literal(0);
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return ToBooleanExpression.literal(false);
}
}
@@ -0,0 +1,39 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
public interface ExpressionTemplate{
ToStringExpression instantiateWithStringResult();
ToDoubleExpression instantiateWithDoubleResult();
ToBooleanExpression instantiateWithBooleanResult();
}
@@ -0,0 +1,362 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expressions;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
import java.util.Collection;
public class ExpressionTemplates{
public static ExpressionTemplate negate(ExpressionTemplate template){
return new Negation(template);
}
public static ExpressionTemplate and(Collection<ExpressionTemplate> operands){
return new And(operands);
}
public static ExpressionTemplate or(Collection<ExpressionTemplate> operands){
return new Or(operands);
}
public static ExpressionTemplate concat(Collection<ExpressionTemplate> operands){
return new Concatenate(operands);
}
public static ExpressionTemplate equal(ExpressionTemplate a, ExpressionTemplate b){
return new Equal(a, b);
}
public static ExpressionTemplate notEqual(ExpressionTemplate a, ExpressionTemplate b){
return new NotEqual(a, b);
}
public static ExpressionTemplate equalIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
return new EqualIgnoreCase(a, b);
}
public static ExpressionTemplate notEqualIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
return new NotEqualIgnoreCase(a, b);
}
public static ExpressionTemplate greater(ExpressionTemplate a, ExpressionTemplate b){
return new Greater(a, b);
}
public static ExpressionTemplate greaterOrEqual(ExpressionTemplate a, ExpressionTemplate b){
return new GreaterOrEqual(a, b);
}
public static ExpressionTemplate less(ExpressionTemplate a, ExpressionTemplate b){
return new Less(a, b);
}
public static ExpressionTemplate lessOrEqual(ExpressionTemplate a, ExpressionTemplate b){
return new LessOrEqual(a, b);
}
public static ExpressionTemplate sum(Collection<ExpressionTemplate> operands){
return new Sum(operands);
}
public static ExpressionTemplate product(Collection<ExpressionTemplate> operands){
return new Product(operands);
}
public static ExpressionTemplate sub(ExpressionTemplate a, ExpressionTemplate b){
return new Sub(a, b);
}
public static ExpressionTemplate div(ExpressionTemplate a, ExpressionTemplate b){
return new Div(a, b);
}
public static ExpressionTemplate negateNumber(ExpressionTemplate template){
return new NegationNumber(template);
}
private static class Negation extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate template;
Negation(ExpressionTemplate template){
this.template = template;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.negate(template.instantiateWithBooleanResult());
}
}
private static class And extends AbstractBooleanExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
And(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.and(operands.stream().map(ExpressionTemplate::instantiateWithBooleanResult).toList());
}
}
private static class Or extends AbstractBooleanExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
Or(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.or(operands.stream().map(ExpressionTemplate::instantiateWithBooleanResult).toList());
}
}
private static class Concatenate extends AbstractStringExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
Concatenate(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToStringExpression instantiateWithStringResult(){
return Expressions.concat(operands.stream().map(ExpressionTemplate::instantiateWithStringResult).toList());
}
}
private static class Equal extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Equal(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.equal(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class NotEqual extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
NotEqual(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.notEqual(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class EqualIgnoreCase extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
EqualIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.equalIgnoreCase(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class NotEqualIgnoreCase extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
NotEqualIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.notEqualIgnoreCase(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class Greater extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Greater(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.greaterThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class GreaterOrEqual extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
GreaterOrEqual(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.greaterOrEqualThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class Less extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Less(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.lessThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class LessOrEqual extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
LessOrEqual(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.lessOrEqualThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class Sum extends AbstractDoubleExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
Sum(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.sum(operands.stream().map(ExpressionTemplate::instantiateWithDoubleResult).toList());
}
}
private static class Product extends AbstractDoubleExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
Product(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.product(operands.stream().map(ExpressionTemplate::instantiateWithDoubleResult).toList());
}
}
private static class Sub extends AbstractDoubleExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Sub(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.sub(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class Div extends AbstractDoubleExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Div(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.div(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class NegationNumber extends AbstractDoubleExpressionTemplate{
private final ExpressionTemplate template;
NegationNumber(ExpressionTemplate template){
this.template = template;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.negateNumber(template.instantiateWithDoubleResult());
}
}
}
@@ -0,0 +1,42 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.tokens;
public class BooleanToken extends Token{
public static final BooleanToken TRUE = new BooleanToken(true);
public static final BooleanToken FALSE = new BooleanToken(false);
private final boolean value;
public BooleanToken(boolean value){
super("BOOLEAN(" + value + ")");
this.value = value;
}
public boolean getValue(){
return value;
}
}
@@ -0,0 +1,47 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.tokens;
public class DefaultTokens{
public static final Token AND = new Token("AND");
public static final Token OR = new Token("OR");
public static final Token OPENING_PARENTHESIS = new Token("OPENING_PARENTHESIS");
public static final Token CLOSING_PARENTHESIS = new Token("CLOSING_PARENTHESIS");
public static final Token EQUAL = new Token("EQUAL");
public static final Token NOT_EQUAL = new Token("NOT_EQUAL");
public static final Token EQUAL_IGNORE_CASE = new Token("EQUAL_IGNORE_CASE");
public static final Token NOT_EQUAL_IGNORE_CASE = new Token("NOT_EQUAL_IGNORE_CASE");
public static final Token NEGATION = new Token("NEGATION");
public static final Token GREATER_THAN = new Token("GREATER_THAN");
public static final Token GREATER_OR_EQUAL_THAN = new Token("GREATER_OR_EQUAL_THAN");
public static final Token LESSER_THAN = new Token("LESSER_THAN");
public static final Token LESSER_OR_EQUAL_THAN = new Token("LESSER_OR_EQUAL_THAN");
public static final Token CONCAT_STRING = new Token("CONCAT_STRING");
public static final Token ADD = new Token("ADD");
public static final Token SUB = new Token("SUB");
public static final Token MULT = new Token("MULT");
public static final Token DIV = new Token("DIV");
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.tokens;
public class NumberToken extends Token{
private final double value;
public NumberToken(double value){
super("NUMBER(" + value + ")");
this.value = value;
}
public double getValue(){
return value;
}
}
@@ -0,0 +1,42 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.tokens;
import ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.Placeholder;
public class PlaceholderToken extends Token{
private final Placeholder value;
public PlaceholderToken(Placeholder value){
super("PLACEHOLDER");
this.value = value;
}
public Placeholder getValue(){
return value;
}
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.tokens;
public class StringToken extends Token{
private final String value;
public StringToken(String value){
super("STRING(" + value + ")");
this.value = value;
}
public String getValue(){
return value;
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
* Copyright (c) 2022-2024 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,11 +23,18 @@
*
*/
package ch.andre601.advancedserverlist.versionuploader.hangar.version;
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens;
public record Namespace(String owner, String slug){
public class Token{
private final String id;
public Token(String id){
this.id = id;
}
@Override
public String toString(){
return owner() + "/" + slug();
return id;
}
}
@@ -0,0 +1,53 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.tokens.readers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.StringToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.text.ParsePosition;
public class NonQuotedLiteralTokenReader extends TokenReader{
public NonQuotedLiteralTokenReader(int priority){
super(priority);
}
@Override
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
int startIndex = position.getIndex();
int index = position.getIndex();
while(++index < text.length() && !Character.isWhitespace(text.charAt(index)))
;
position.setIndex(index);
return new StringToken(text.substring(startIndex, position.getIndex()));
}
}
@@ -0,0 +1,55 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.tokens.readers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.NumberToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.Locale;
public class NumberTokenReader extends TokenReader{
private final NumberFormat format = NumberFormat.getInstance(Locale.ROOT);
public NumberTokenReader(int priority){
super(priority);
}
@Override
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
int previous = position.getIndex();
Number number = format.parse(text, position);
if(position.getIndex() != previous)
return new NumberToken(number.doubleValue());
return null;
}
}
@@ -0,0 +1,61 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.tokens.readers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.text.ParsePosition;
public class PatternTokenReader extends TokenReader{
private final Token token;
private final String pattern;
private final boolean ignoreCase;
public PatternTokenReader(Token token, String pattern){
this(token, pattern, true);
}
public PatternTokenReader(Token token, String pattern, boolean ignoreCase){
super(pattern.length());
this.token = token;
this.pattern = pattern;
this.ignoreCase = ignoreCase;
}
@Override
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
if(text.regionMatches(ignoreCase, position.getIndex(), pattern, 0, pattern.length())){
position.setIndex(position.getIndex() + pattern.length());
return token;
}
return null;
}
}
@@ -0,0 +1,50 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.tokens.readers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.PlaceholderParser;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.PlaceholderToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.text.ParsePosition;
public class PlaceholderTokenReader extends TokenReader{
public PlaceholderTokenReader(int priority){
super(priority);
}
@Override
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
if(position.getIndex() + 1 < text.length() && text.charAt(position.getIndex()) == '$' && text.charAt(position.getIndex() + 1) == '{'){
position.setIndex(position.getIndex() + 2);
return new PlaceholderToken(PlaceholderParser.parse(text, position, player, server));
}
return null;
}
}
@@ -0,0 +1,62 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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.conditions.tokens.readers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.StringToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.text.ParsePosition;
public class QuotedLiteralTokenReader extends TokenReader{
private final char quote;
public QuotedLiteralTokenReader(int priority, char quote){
super(priority);
this.quote = quote;
}
@Override
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
if(position.getIndex() < text.length() && text.charAt(position.getIndex()) == quote){
int startIndex = position.getIndex();
position.setIndex(position.getIndex() + 1);
while(position.getIndex() < text.length() && quote != text.charAt(position.getIndex()))
position.setIndex(position.getIndex() + 1);
position.setIndex(position.getIndex() + 1);
return new StringToken(text.substring(startIndex + 1, position.getIndex() - 1));
}
return null;
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
* Copyright (c) 2022-2024 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,34 +23,25 @@
*
*/
package ch.andre601.advancedserverlist.core.objects;
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
public class GenericServerImpl implements GenericServer{
import java.text.ParsePosition;
public abstract class TokenReader{
private final int online;
private final int max;
private final String host;
private final int priority;
public GenericServerImpl(int online, int max, String host){
this.online = online;
this.max = max;
this.host = host;
public TokenReader(int priority){
this.priority = priority;
}
@Override
public int getPlayersOnline(){
return online;
public int getPriority(){
return priority;
}
@Override
public int getPlayersMax(){
return max;
}
@Override
public String getHost(){
return host;
}
public abstract Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server);
}
@@ -70,21 +70,34 @@ public class FaviconHandler<F>{
private CompletableFuture<F> convert(String input, Function<BufferedImage, F> function){
return CompletableFuture.supplyAsync(() -> {
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Getting BufferedImage for input '%s'...", input);
BufferedImage img = resolveImage(core, input);
if(img == null)
if(img == null){
core.getPlugin().getPluginLogger().debugWarn(FaviconHandler.class, "No BufferedImage could be created!");
return null;
}
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Received BufferedImage! Applying it...");
return function.apply(img);
}, faviconThreadPool);
}
private BufferedImage resolveImage(AdvancedServerList<F> core, String input){
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resolving favicon for input '%s'...", input);
InputStream stream;
if(input.toLowerCase(Locale.ROOT).startsWith("https://")){
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "URL detected. Getting file from it...");
stream = getFromUrl(core, input);
}else
if(input.toLowerCase(Locale.ROOT).endsWith(".png")){
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Image file detected. Trying to reolve it...");
File folder = core.getPlugin().getFolderPath().resolve("favicons").toFile();
if(!folder.exists()){
core.getPlugin().getPluginLogger().warn("Cannot get Favicon %s from favicons folder. Folder doesn't exist!", input);
@@ -95,12 +108,16 @@ public class FaviconHandler<F>{
try{
stream = new FileInputStream(file);
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resolved image file!");
}catch(IOException ex){
core.getPlugin().getPluginLogger().warn("Cannot create Favicon from File %s.", input);
core.getPlugin().getPluginLogger().warn("Cause: %s", ex.getMessage());
return null;
}
}else{
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Possible player name/UUID detected. Using https://mc-heads.net/avatar/%s/64...", input);
stream = getFromUrl(core, "https://mc-heads.net/avatar/" + input + "/64");
}
@@ -116,6 +133,8 @@ public class FaviconHandler<F>{
return null;
}
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resizing image to 64x64 pixels...");
BufferedImage favicon = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
Graphics2D img = favicon.createGraphics();
@@ -123,6 +142,7 @@ public class FaviconHandler<F>{
img.drawImage(original, 0, 0, 64, 64, null);
img.dispose();
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Image resized!");
return favicon;
}catch(IOException ex){
core.getPlugin().getPluginLogger().warn("Unable to create Favicon. Encountered IOException during creation.");
@@ -133,11 +153,14 @@ public class FaviconHandler<F>{
private InputStream getFromUrl(AdvancedServerList<F> core, String url){
try{
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resolving URL '%s'...", url);
URL faviconUrl = new URL(url);
URLConnection connection = faviconUrl.openConnection();
connection.setRequestProperty("User-Agent", "AdvancedServerList/" + core.getVersion());
connection.connect();
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "URL resolved!");
return connection.getInputStream();
}catch(IOException ex){
core.getPlugin().getPluginLogger().warn("Error while connecting to %s for Favicon creation.", url);
@@ -53,18 +53,21 @@ public class ProfileManager{
String favicon = resolveFavicon(entry, defEntry);
boolean isHidePlayersEnabled = resolveHidePlayersEnabled(entry, defEntry);
boolean isExtraPlayersEnabled = resolveExtraPlayersEnabled(entry, defEntry);
boolean isMaxPlayersEnabled = resolveMaxPlayersEnabled(entry, defEntry);
Integer extraPlayersCount = resolveExtraPlayersCount(entry, defEntry);
Integer maxPlayersCount = resolveMaxPlayersCount(entry, defEntry);
return new ProfileEntry(motd, players, playerCountText, favicon,
NullBool.resolve(isHidePlayersEnabled), NullBool.resolve(isExtraPlayersEnabled), extraPlayersCount);
NullBool.resolve(isHidePlayersEnabled), NullBool.resolve(isExtraPlayersEnabled), NullBool.resolve(isMaxPlayersEnabled),
extraPlayersCount, maxPlayersCount);
}
public static ServerListProfile resolveProfile(AdvancedServerList core, GenericPlayer player, GenericServer server){
public static ServerListProfile resolveProfile(AdvancedServerList<?> core, GenericPlayer player, GenericServer server){
for(ServerListProfile profile : core.getFileHandler().getProfiles()){
if(profile.isInvalidProfile())
continue;
if(profile.evalConditions(player, server))
if(profile.evalConditions(core.getExpressionEngine(), core.getPlugin().getPluginLogger(), player, server))
return profile;
}
@@ -78,7 +81,9 @@ public class ProfileManager{
String favicon = node.node("favicon").getString("");
NullBool hidePlayers = resolveNullBool(node, "playerCount", "hidePlayers");
NullBool extraPlayersEnabled = resolveNullBool(node, "playerCount", "extraPlayers", "enabled");
Integer extraPlayers = resolveNullableInt(node);
NullBool maxPlayersEnabled = resolveNullBool(node, "playerCount", "maxPlayers", "enabled");
Integer extraPlayers = resolveNullableInt(node, "playerCount", "extraPlayers", "amount");
Integer maxPlayers = resolveNullableInt(node, "playerCount", "maxPlayers", "amount");
return new ProfileEntry.Builder()
.setMotd(motd)
@@ -87,7 +92,9 @@ public class ProfileManager{
.setFavicon(favicon)
.setHidePlayersEnabled(hidePlayers)
.setExtraPlayersEnabled(extraPlayersEnabled)
.setExtraPlayerCount(extraPlayers)
.setMaxPlayersEnabled(maxPlayersEnabled)
.setExtraPlayersCount(extraPlayers)
.setMaxPlayersCount(maxPlayers)
.build();
}
@@ -150,6 +157,13 @@ public class ProfileManager{
return profile.extraPlayersEnabled().getOrDefault(false);
}
private static boolean resolveMaxPlayersEnabled(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || !checkOption(profile.maxPlayersEnabled()))
return defaultProfile.maxPlayersEnabled().getOrDefault(false);
return profile.maxPlayersEnabled().getOrDefault(false);
}
private static Integer resolveExtraPlayersCount(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.extraPlayersCount() == null)
return defaultProfile.extraPlayersCount() == null ? 0 : defaultProfile.extraPlayersCount();
@@ -157,6 +171,13 @@ public class ProfileManager{
return profile.extraPlayersCount();
}
private static Integer resolveMaxPlayersCount(ProfileEntry profile, ProfileEntry defaultProfile){
if(profile == null || profile.maxPlayersCount() == null)
return defaultProfile.maxPlayersCount() == null ? 0 : defaultProfile.maxPlayersCount();
return profile.maxPlayersCount();
}
private static List<String> resolveList(ConfigurationNode node, Object... path){
try{
return node.node(path).getList(String.class);
@@ -172,10 +193,10 @@ public class ProfileManager{
return NullBool.resolve(node.node(path).getBoolean());
}
private static Integer resolveNullableInt(ConfigurationNode node){
if(node.node("playerCount", "extraPlayers", "amount").virtual())
private static Integer resolveNullableInt(ConfigurationNode node, Object... path){
if(node.node(path).virtual())
return null;
return node.node("playerCount", "extraPlayers", "amount").getInt();
return node.node(path).getInt();
}
}
@@ -52,8 +52,10 @@ public class ProfileSerializer implements TypeSerializer<ProfileEntry>{
node.node("playerCount", "hover").set(profile.players());
node.node("playerCount", "text").set(profile.playerCountText());
node.node("favicon").set(profile.favicon());
node.node("playerCount", "hidePlayers").set(profile.hidePlayersEnabled());
node.node("playerCount", "extraPlayers", "enabled").set(profile.extraPlayersEnabled());
node.node("playerCount", "extraPlayers", "amount").set(profile.extraPlayersCount());
node.node("playerCount", "hidePlayers").set(profile.hidePlayersEnabled().getOrDefault(false));
node.node("playerCount", "extraPlayers", "enabled").set(profile.extraPlayersEnabled().getOrDefault(false));
node.node("playerCount", "extraPlayers", "amount").set((profile.extraPlayersCount() == null) ? 0 : profile.extraPlayersCount());
node.node("playerCount", "maxPlayers", "enabled").set(profile.maxPlayersEnabled().getOrDefault(false));
node.node("playerCount", "maxPlayers", "amount").set((profile.maxPlayersCount() == null) ? 0 : profile.maxPlayersCount());
}
}
+12 -1
View File
@@ -31,10 +31,21 @@ disableCache: false
#
checkUpdates: true
#
# Should debug mode be enabled?
#
# When set to true will AdvancedServerList print additional messages to the console prefixed with "[DEBUG]".
# It is recommended to only enable this when having problems or when being told to by the plugin dev, as it could
# otherwise cause significant spam in your console.
#
# Defaults to false when not present.
#
debug: false
#
# DO NOT EDIT!
#
# This is used internally to determine if the config needs to be migrated.
# Changing or even removing this option could result in your config being broken.
#
config-version: 2
config-version: ${plugin.config.version}
+51 -13
View File
@@ -2,15 +2,24 @@
# Set the priority of this profile.
# Higher number = Higher priority.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#priority
# Read more: https://asl.andre601.ch/profiles/#priority
#
priority: 0
#
# Set conditions that need to me met to show this profile.
# You can use keywords 'and' or 'or' (Or alternatively '&&' or `||`) to make more complex condition sets.
#
# Read more: https://asl.andre601.ch/profiles/#condition
#
# condition: '${player protocol} < 759'
#
#
# Set conditions that needs to be met.
# Only when all conditions return true will the profile be shown (Given no profile with higher priority is used).
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#conditions
# Read more: https://asl.andre601.ch/profiles/#conditions
#
#conditions:
# - '{playerVersion} < 759'
@@ -25,7 +34,7 @@ priority: 0
#
# 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
# Read more: https://asl.andre601.ch/profiles/#profiles
#
#profiles:
# - motd:
@@ -49,7 +58,7 @@ priority: 0
#
# Remove this option or set it to motd: [] to not alter the MOTD.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#motds
# Read more: https://asl.andre601.ch/profiles/#motd
#
motd:
- '<grey>Line 1'
@@ -64,14 +73,14 @@ motd:
#
# Remove this option or set to favicon: '' to not replace the Favicon.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#favicon
# Read more: https://asl.andre601.ch/profiles/#favicon
#
favicon: ''
#
# Contains various options to manipulate the player count (Text displaying online and max players allowed).
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#playercount
# Read more: https://asl.andre601.ch/profiles/#playercount
#
playerCount:
#
@@ -82,7 +91,7 @@ playerCount:
#
# Defaults to false when not present.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#hideplayers
# Read more: https://asl.andre601.ch/profiles/#hideplayers
#
hidePlayers: false
#
@@ -90,7 +99,7 @@ playerCount:
#
# 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
# Read more: https://asl.andre601.ch/profiles/#hover
#
hover:
- '<grey>Line 1'
@@ -104,24 +113,24 @@ playerCount:
#
# 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
# Read more: https://asl.andre601.ch/profiles/#text
#
text: ''
#
# Allows you to modify the max player count displayed.
# Note that this will affect ${server playersMax} (Except for when used in conditions).
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#extraPlayers
# Read more: https://asl.andre601.ch/profiles/#extraplayers
#
extraPlayers:
#
# Enables/Disables the extraPlayers option.
# When enabled will the total amount of players allowed be modified to the current
# When enabled will the total amount of players allowed to join be modified to the current
# number of online players + 'amount'
#
# Defaults to false when not present.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#enabled
# Read more: https://asl.andre601.ch/profiles/#extraplayers-enabled
#
enabled: false
#
@@ -134,6 +143,35 @@ playerCount:
#
# Defaults to 0 when not present.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#amount
# Read more: https://asl.andre601.ch/profiles/#extraplayers-amount
#
amount: 0
#
# Allows you to set the max players that could join your server.
# Note that this option influences the '${server playersMax}' placeholder.
#
# The settings of this option have no effect should 'extraPlayers' be enabled
#
# Read more: https://asl.andre601.ch/profiles/#maxplayers
#
maxPlayers:
#
# Enables/Disables the maxPlayers option.
# When enabled will the total amount of players allowed to join be changed to what 'amount' is set to.
#
# Defaults to false when not present.
#
# Read more: https://asl.andre601.ch/profiles/#maxplayers-enabled
#
enabled: false
#
# Sets the number to display for the max number of players allowed to join your server.
#
# Example:
# Setting this option to 0 (Default) while 1 player is online would display '1/0'
#
# Defaults to 0 if not set.
#
# Read more: https://asl.andre601.ch/profiles/#maxplayers-amount
#
amount: 0
+2 -1
View File
@@ -23,4 +23,5 @@
#
#
version=${plugin.version}
version=${plugin.version}
config-version=${plugin.config.version}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
* Copyright (c) 2022-2024 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,30 +23,38 @@
*
*/
package ch.andre601.advancedserverlist.spigot.commands;
package ch.andre601.advancedserverlist.test;
import ch.andre601.advancedserverlist.core.interfaces.commands.CmdSender;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.command.CommandSender;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
public class SpigotCmdSender implements CmdSender{
private final CommandSender sender;
private final BukkitAudiences bukkitAudiences;
public SpigotCmdSender(CommandSender sender, BukkitAudiences bukkitAudiences){
this.sender = sender;
this.bukkitAudiences = bukkitAudiences;
public class DummyPluginLogger implements PluginLogger{
@Override
public void debug(Class<?> clazz, String msg, Object... args){
info("[DEBUG] [" + clazz.getSimpleName() + "] " + msg, args);
}
@Override
public boolean hasPermission(String permission){
return sender.hasPermission(permission) || sender.hasPermission("advancedserverlist.admin");
public void debugWarn(Class<?> clazz, String msg, Object... args){
warn("[DEBUG] [" + clazz.getSimpleName() + "] " + msg, args);
}
@Override
public void sendMsg(String msg, Object... args){
bukkitAudiences.sender(sender).sendMessage(ComponentParser.text(String.format(msg, args)).toComponent());
public void info(String msg, Object... args){
System.out.printf((msg) + "%n", args);
}
@Override
public void warn(String msg, Object... args){
System.out.printf((msg) + "%n", args);
}
@Override
public void warn(String msg, Throwable throwable){
System.out.printf((msg) + "%n", throwable);
}
@Override
public void warn(String msg, Throwable throwable, Object... args){
System.out.printf((msg) + "%n", args);
}
}
@@ -0,0 +1,66 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 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 ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionEngine;
import org.junit.jupiter.api.Test;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ExpressionParserTests{
private final ExpressionEngine expressionEngine = new ExpressionEngine();
private final DummyPluginLogger logger = new DummyPluginLogger();
private final Map<String, Boolean> testValuesMap = getTestMap();
@Test
public void testBasicExpressionResults(){
for(Map.Entry<String, Boolean> values : testValuesMap.entrySet()){
logger.info("TEST[expression=\"%s\", expected=%b]", values.getKey(), values.getValue());
boolean result = expressionEngine.compile(values.getKey(), logger, null, null).instantiateWithBooleanResult().evaluate();
logger.info("Result (output, isExpected): " + result + ", " + (result == values.getValue()));
assertEquals(result, values.getValue());
}
}
private Map<String, Boolean> getTestMap(){
return Map.of(
"20 > 10", true,
"10 > 20", false,
"10 = 10", true,
"10 = 20", false,
"(10 - 5) > (1 + 1)", true,
"(10 - 10) > (1 + 1)", false,
"100 > 50 and 50 < 100", true,
"100 < 50 and 50 > 100", false,
"true or 100 > 10", true,
"false or 100 < 10", false
);
}
}
@@ -26,7 +26,9 @@
package ch.andre601.advancedserverlist.test;
import com.unascribed.flexver.FlexVerComparator;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class FlexVerTests{
@@ -286,7 +288,9 @@ public class FlexVerTests{
private void compare(String version1, String comparator, String version2, int expected){
String expression = version1 + " " + comparator + " " + version2 + "?";
int result = FlexVerComparator.compare(version1, version2);
System.out.printf("│ %-24s %5b │\n", expression, FlexVerComparator.compare(version1, version2) == expected);
assertEquals(result, expected);
}
}
+58
View File
@@ -0,0 +1,58 @@
#
# Modified version of Squidfunk's shortcodes.py file for Material for MkDocs.
#
# It was altered to create compact admonition-like boxes to display in the documentation.
#
# Original shortcodes.py file:
# https://github.com/squidfunk/mkdocs-material/blob/56b96b4d799174d48d36613d70ffac9b964171cc/material/overrides/hooks/shortcodes.py
#
from __future__ import annotations
import posixpath
import re
from mkdocs.config.defaults import MkDocsConfig
from mkdocs.structure.files import File, Files
from mkdocs.structure.pages import Page
from re import Match
def on_page_markdown(
markdown: str, *, page: Page, config: MkDocsConfig, files: Files
):
# Replace callback
def replace(match: Match):
type, args = match.groups()
args = args.strip()
if type == "abstract": return _admo(text = args, type = "abstract")
elif type == "info": return _admo(text = args, type = "info")
elif type == "tip": return _admo(text = args, type = "tip")
elif type == "success": return _admo(text = args, type = "success")
elif type == "question": return _admo(text = args, type = "question")
elif type == "warning": return _admo(text = args, type = "warning")
elif type == "failure": return _admo(text = args, type = "failure")
elif type == "danger": return _admo(text = args, type = "danger")
elif type == "bug": return _admo(text = args, type = "bug")
elif type == "example": return _admo(text = args, type = "example")
elif type == "quote": return _admo(text = args, type = "quote")
elif type == "deprecated": return _admo(text = args, type = "deprecated")
else: return _admo(text = args)
# Otherwise, raise an error
raise RuntimeError(f"Unknown shortcode: {type}")
# Find and replace all external asset URLs in current page
return re.sub(
r"<!-- admo:(\w+)(.*?) -->",
replace, markdown, flags = re.I | re.M
)
def _admo(text: str = "", type: str = ""):
classes = f"mdx-grid-wrapper mdx-admo--{type}" if type else "mdx-grid-wrapper"
return "".join([
f"<div class=\"{classes}\">",
f"<div class=\"mdx-grid-child mdx-grid-child--icon\"></div>",
f"<div class=\"mdx-grid-child\">{text}</div>"
"</div>",
])
+17 -2
View File
@@ -33,7 +33,9 @@
{% endif %}
{% set desc = "" %}
{% if summary.description %}
{% if summary.deprecated %}
{% set desc = "<api__deprecated></api__deprecated><br>" ~ summary.deprecated.split("<br>")[0] %}
{% elif summary.description %}
{% set desc = summary.description.split("<br>")[0] %}
{% endif %}
@@ -53,7 +55,7 @@
{% set final_name.name = final_name.name ~ ")" %}
{% endif %}
{% if details_type and details_type == "method" %}
{% if details_type and details_type == "method" %}
{% if modifiers.name %}
<td><code>{{ modifiers.name }}</code></td>
{% else %}
@@ -124,6 +126,10 @@
{% endif %}
<h3 id="{{ final_name.name | lower() | replace(' ', '-') | e }}">
{% if detail.deprecated %}
<api__deprecated></api__deprecated>
{% endif %}
{% for attribute in detail.attributes %}
<api__{{- attribute -}}></api__{{- attribute -}}>
{% endfor %}
@@ -142,6 +148,15 @@
<code>{{ final_name.name | e }}</code><a href="#{{ final_name.name | lower() | replace(' ', '-') | e }}" class="headerlink" title="Permanent link"></a>
</h3>
{% if detail.deprecated %}
<div class="admonition deprecated">
<div class="admonition-title">Deprecation Warning</div>
<p>
{{ detail.deprecated }}
</p>
</div>
{% endif %}
{% if detail.description %}
<p class="api-detail__description">
{{ detail.description }}
+42
View File
@@ -0,0 +1,42 @@
<!-- Tags -->
{% if "material/tags" in config.plugins and tags %}
{% include "partials/tags.html" %}
{% endif %}
<!-- Actions -->
{% include "partials/actions.html" %}
{% if config.extra.github_repository %}
<div class="admonition info">
<p class="admonition-title">Moved</p>
<p>
The documenation has been moved and can now be found at <a href="https://asl.andre601.ch" target="_blank" rel="noreferral nofollow noopener"><strong>asl.andre601.ch</strong></a>.<br>
This page in particular can be found at <a href="https://asl.andre601.ch/{{ page.url }}" target="_blank" rel="noreferral nofollow noopener"><strong>asl.andre601.ch/{{ page.url }}</strong></a>.
</p>
</div>
{% endif %}
<!--
Hack: check whether the content contains a h1 headline. If it doesn't, the
page title (or respectively site name) is used as the main headline.
-->
{% if "\x3ch1" not in page.content %}
<h1>{{ page.title | d(config.site_name, true)}}</h1>
{% endif %}
<!-- Page content -->
{{ page.content }}
<!-- Source file information -->
{% if page.meta and (
page.meta.git_revision_date_localized or
page.meta.revision_date
) %}
{% include "partials/source-file.html" %}
{% endif %}
<!-- Was this page helpful? -->
{% include "partials/feedback.html" %}
<!-- Comment system -->
{% include "partials/comments.html" %}
-17
View File
@@ -1,17 +0,0 @@
<a
href="{{ config.repo_url}}"
title="{{ lang.t('source') }}"
class="md-source"
target="_blank"
rel="nofollow noreferral noopener"
>
<div class="md-source__icon md-icon">
{% set icon = config.theme.icon.repo or "fontawesome/brands/git-alt" %}
{% include ".icons/" ~ icon ~ ".svg" %}
</div>
<div class="md-source__repository">
{{ config.repo_name }}
<ul class="md-source__facts" data-md-component="codeberg-stats">
</ul>
</div>
</a>
+4 -4
View File
@@ -1,9 +1,9 @@
nav:
- Home:
- index.md
- commands.md
- Home: index.md
- getting-started
- commands
- profiles
- examples
- migration
- api
- placeholderapi
- PlaceholderAPI: placeholderapi
+1
View File
@@ -0,0 +1 @@
<div class="mdx-badge"><span class="mdx-badge__icon">[:octicons-tag-24:](changelog.md#v3.1.0 'View latest Release Changelog')</span><span class="mdx-badge__text">[v3.1.0](changelog.md#v3.1.0 'View latest Release Changelog')</span></div>
+1
View File
@@ -0,0 +1 @@
<div class="mdx-badge"><span class="mdx-badge__icon" >[:octicons-alert-24:](changelog.md)</span><span class="mdx-badge__text">[v3.1.0](changelog.md#v3.1.0 'View latest Release Changelog')</span></div>
+38 -4
View File
@@ -7,7 +7,34 @@ icon: octicons/log-24
This page lists the recent changes made towards the AdvancedServerListAPI.
They are ordered newest to oldest.
## v3.0.0
## v3.1.0 { #v3.1.0 }
### :octicons-plus-circle-24:{ .changelog-added title="Added" } Added { #v3.1.0-added }
- New getters in [`ProfileEntry`][profileentry]:
- [`maxPlayersEnabled()`][maxplayersenabled] - Returns the value for `playerCount -> maxPlayers -> enabled` as `NullBool`
- [`maxPlayersCount()`][maxplayerscount] - Returns the value of `playerCount -> maxPlayers -> amount` as nullable `Integer`
- New setters in [`ProfileEntry.Builder`][profileentry.builder]:
- [`setMaxPlayersEnabled(NullBool)`][setmaxplayersenabled] - Sets whether the max players feature is enabled or not.
- [`setMaxPlayersCount(Integer)`][setmaxplayerscount] - Sets the number to use for the max players count.
- [`setExtraPlayersCount(Integer)`][setextraplayersecount] - Replacement for [deprecated `setExtraPlayerCount(Integer)` method](#v3.1.0-deprecated).
### :octicons-zap-24:{ .changelog-breaking title="Deprecated" } Deprecated { #v3.1.0-deprecated }
- `setExtraPlayerEnabled(Integer)` in `ProfileEntry.Builder` - Typo in method name.
[profileentry]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/index.md
[maxplayersenabled]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/index.md#maxplayersenabled()
[maxplayerscount]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/index.md#maxplayerscount()
[profileentry.builder]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/builder.md
[setmaxplayersenabled]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/builder.md#setmaxplayersenabled(nullbool)
[setmaxplayerscount]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/builder.md#setmaxplayerscount(integer)
[setextraplayersecount]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/builder.md#setextraplayerscount(integer)
----
## v3.0.0 { #v3.0.0 }
### :octicons-alert-24:{ .changelog-breaking title="Breaking Changes" } Breaking Changes { #v3-breaking }
@@ -25,14 +52,18 @@ They are ordered newest to oldest.
- All previously deprecated `getX()` methods from the `ProfileEntry` record
## v2.1.0
----
## v2.1.0 { #v2.1.0 }
### :octicons-pencil-24:{ .changelog-changed title="Changed" } Changed { #v2.1.0-changed }
- Turned `ProfileEntry` class into a record
- Former `getX()` methods are now deprecated in favour of the record's own `x()` methods (i.e. `getMotd()` -> `motd()`)
## v2.0.0
----
## v2.0.0 { #v2.0.0 }
### :octicons-alert-24:{ .changelog-breaking title="Breaking Changes" } Breaking Changes { #v2-breaking }
@@ -61,7 +92,9 @@ They are ordered newest to oldest.
- `UnsupportedAPIAccessException` as it is no longer used in the API itself.
## v1.0.0
----
## v1.0.0 { #v1.0.0 }
### :octicons-plus-circle-24:{ .changelog-added title="Added" } Added { #v1-added }
@@ -78,5 +111,6 @@ Templates for changelog
### :octicons-plus-circle-24:{ .changelog-added title="Added" } Added { #v-added }
### :octicons-pencil-24:{ .changelog-changed title="Changed" } Changed { #v-changed }
### :octicons-trash-24:{ .changelog-removed title="Removed" } Removed { #v-removed }
### :octicons-zap-24:{ .changelog-deprecated title="Deprecated" } Deprecated { #v-deprecated }
-->
+327 -94
View File
@@ -9,87 +9,95 @@ It provides a way for your plugin to provide its own placeholders that should be
## Add dependency
Add the following to your `build.gradle` or `pom.xml` file to use the API:
Add the following to your `pom.xml`, `build.gradle` or `build.gradle.kts` depending on what you use:
=== ":simple-gradle: Gradle"
/// tab | :simple-apachemaven: Maven
```xml title="pom.xml"
<repositories>
<repository>
<id>jitpack</id>
<url>https://jitpack.io/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>api</artifactId>
<version>{apiVersion}</version>
<scope>provided</scope>
</dependency>
<!-- Optional platform dependencies -->
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>platform-bukkit</artifactId>
<version>{apiVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>platform-bungeecord</artifactId>
<version>{apiVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>platform-velocity</artifactId>
<version>{apiVersion}</version>
<scope>provided</scope>
</dependency>
</dependencies>
```
///
/// tab | :simple-gradle: Gradle
```groovy title="build.gradle"
repositorories {
maven { url = 'https://jitpack.io/' }
}
dependencies {
compileOnly 'ch.andre601.asl-api:api:{apiVersion}'
[![latest_release][release]][api-repo]
// Optional platform dependencies
compileOnly 'ch.andre601.asl-api:platform-bukkit:{apiVersion}'
compileOnly 'ch.andre601.asl-api:platform-bungeecord:{apiVersion}'
compileOnly 'ch.andre601.asl-api:platform-velocity:{apiVersion}'
}
```
///
/// tab | :simple-gradle: Gradle (KTS)
```kotlin title="build.gradle.kts"
repositories {
maven("https://jitpack.io")
}
dependencies {
compileOnly("ch.andre601.asl-api:api:{apiVersion}")
Make sure to replace `{version}` with the version displayed above.
```groovy title="build.gradle"
repositorories {
maven { url = 'https://jitpack.io/' }
}
dependencies {
implementation 'ch.andre601.asl-api:api:{version}'
// Optional platform dependencies
implementation 'ch.andre601.asl-api:platform-bukkit:{version}'
implementation 'ch.andre601.asl-api:platform-bungeecord:{version}'
implementation 'ch.andre601.asl-api:platform-velocity:{version}'
}
```
// Optional platform dependencies
compileOnly("ch.andre601.asl-api:platform-bukkit:{apiVersion}")
compileOnly("ch.andre601.asl-api:platform-bungeecord:{apiVersion}")
compileOnly("ch.andre601.asl-api:platform-velocity:{apiVersion}")
}
```
///
=== ":simple-apachemaven: Maven"
[![latest_release][release]][api-repo]
Make sure to replace `{version}` with the version displayed above.
```xml title="pom.xml"
<repositories>
<repository>
<id>jitpack</id>
<url>https://jitpack.io/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>api</artifactId>
<version>{version}</version>
</dependency>
<!-- Optional platform dependencies -->
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>platform-bukkit</artifactId>
<version>{version}</version>
</dependency>
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>platform-bungeecord</artifactId>
<version>{version}</version>
</dependency>
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>platform-velocity</artifactId>
<version>{version}</version>
</dependency>
</dependencies>
```
## Adding your own Placeholders
[release]: https://img.shields.io/github/v/tag/Andre601/asl-api?labelColor=252631&color=292a36&style=for-the-badge&label=Latest%20Release:
[api-repo]: https://github.com/Andre601/asl-api
<!-- admo:info This requires the main api module -->
## Add own placeholders
The API allows you to add your own placeholders which would be available through the `${<identifier> <values>}` placeholder Pattern in a Server List profile.
To add your own placeholders will you need to do a few steps.
To add your own placeholders, follow these steps:
### 1) Get API instance
### 1. Create a Placeholder class
Use `AdvancedServerListAPI.get()` to retrieve an instance of the currently used AdvancedServerList API.
It will be needed at a later point.
You should first create a new class and make it extend the abstract [`PlaceholderProvider`][placeholderprovider]. This class includes a constructor and a method you need to add, so do that:
### 2) Create a Placeholder class
Make a new class that you want to use for the placeholders and let it extend the `PlaceholderProvider` class of AdvancedServerList.
Your IDE should now tell you to implement/override some methods. Confirm this action and your class should look something alongside this:
```java title="PlaceholderProvider example"
```java
public class MyPlaceholders extends PlaceholderProvider {
public MyPlaceholders(String identifier) {
@@ -103,23 +111,25 @@ public class MyPlaceholders extends PlaceholderProvider {
}
```
It's recommended to replace your generated constructor with a no-args one and set the identifier directly in the `super()`.
For example:
/// tip
You can replace the Constructor with a String argument with a no-args constructor and set the identifier directly in the `super`:
```java
public MyPlaceholders() {
super("myplaceholders");
}
```
///
The next step now would be to handle the different placeholders. These are handled in the `parsePlaceholder` method you had to override.
The `placeholder` String is whatever value was provided after the identifier in `${<identifier> <placeholder>}`. It can contain spaces.
The [`parsePlaceholder(String, GenericPlayer, GenericServer)`][parseplaceholder] method is used by AdvancedServerList to replace a matching placeholder with a value.
What you return is completely up to you. Just keep in mind that returning `null` will be treated as an invalid placeholder by AdvancedServerList, resulting in the placeholder being returned as-is without any changes.
Something to note is, that when returning `null` will AdvancedServerList understand it as an invalid placeholder and return it unchanged.
[placeholderprovider]: reference/api/ch.andre601.advancedserverlist.api/placeholderprovider.md
[parseplaceholder]: reference/api/ch.andre601.advancedserverlist.api/placeholderprovider.md#parseplaceholder(string,-genericplayer,-genericserver)
Here is a small example of the final class:
/// details | Example of final class
type: example
```java title="PlaceholderProvider example"
```java
public class MyPlaceholders extends PlaceholderProvider {
public MyPlaceholders() {
@@ -128,35 +138,258 @@ public class MyPlaceholders extends PlaceholderProvider {
@Override
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server) {
if(placeholder.equals("hello"))
return "Hi!";
if(placeholder.equalsIgnoreCase("hello"))
return "Hello " + player.getName();
return null;
}
}
```
///
### 3) Register the placeholder class
### 2. Register the Placeholders
All that is left to do now is to register your class as a new PlaceholderProvider instance. To do this, get the API instance you retrieved earlier and use `addPlaceholderProvider` with a new instance of your class.
Next step should be to register the placeholder. To achieve this, first obtain an instance of the [`AdvancedServerListAPI`][advancedserverlistapi] by using the static [`get()`][get] method. After that call [`addPlaceholderProvider(PlaceholderProvider placeholderProvider)`][addplaceholderprovider].
Your code may look similar to this:
```java title="Registering PlaceholderProvider class"
AdvancedServerListAPI api = AdvancedServerListAPI.get();
api.addPlaceholderProvider(new MyPlaceholders());
public class MyPlugin extends JavaPlugin {
@Override
public void onEnable() {
AdvancedServerListAPI api = AdvancedServerListAPI.get();
api.addPlaceholderProvider(new MyPlaceholders());
}
}
```
## Events
[advancedserverlistapi]: reference/api/ch.andre601.advancedserverlist.api/advancedserverlistapi.md
[get]: reference/api/ch.andre601.advancedserverlist.api/advancedserverlistapi.md#get()
[addplaceholderprovider]: reference/api/ch.andre601.advancedserverlist.api/advancedserverlistapi.md#addplaceholderprovider(placeholderprovider)
!!! info "Note"
The mentioned event is only accessible through one of the platform dependencies, as those are used in the platform's respective event handler system.
This should register your PlaceholderExpansion as long as it is valid, meaning that the identifier...
v2 of the API adds the `PreServerListSetEvent` to the different platform dependencies to use.
It allows you to modify the ProfileEntry used for the player pinging the server/proxy or even cancelling the event altogether.
- ...is not `null`
- ...is not containing spaces
- ...is not using a name already registered in the API
### 3. Declare AdvancedServerList as (soft)depend
The final thing you should make sure is to define AdvancedServerList as a depend or soft-depend for your plugin, to make sure it loads after AdvancedServerList.
Below are example setups for Spigot, Paper, BungeeCord and Velocity:
/// tab | :simple-spigotmc: Spigot
//// tab | Softdepend
```yaml title="plugin.yml"
name: "MyPlugin"
author: "author"
version: "1.0.0"
main: "com.example.plugin.ExamplePlugin"
softdepend:
- AdvancedServerList
```
////
//// tab | Depend
```yaml title="plugin.yml"
name: "MyPlugin"
author: "author"
version: "1.0.0"
main: "com.example.plugin.ExamplePlugin"
depend:
- AdvancedServerList
```
////
///
/// tab | :fontawesome-solid-paper-plane: Paper
//// tab | Softdepend
```yaml title="paper-plugin.yml"
name: "MyPlugin"
author: "author"
version: "1.0.0"
main: "com.example.plugin.ExamplePlugin"
dependencies:
server:
AdvancedServerList:
load: BEFORE
required: false # Default, not required
```
////
//// tab | Depend
```yaml title="paper-plugin.yml"
name: "MyPlugin"
author: "author"
version: "1.0.0"
main: "com.example.plugin.ExamplePlugin"
dependencies:
server:
AdvancedServerList:
load: BEFORE
required: true
```
////
///
/// tab | :octicons-git-merge-24: BungeeCord
//// tab | Softdepend
```yaml title="bungee.yml"
name: "MyPlugin"
author: "author"
version: "1.0.0"
main: "com.example.plugin.ExamplePlugin"
softDepends:
- AdvancedServerList
```
////
//// tab | Depend
```yaml title="bungee.yml"
name: "MyPlugin"
author: "author"
version: "1.0.0"
main: "com.example.plugin.ExamplePlugin"
depends:
- AdvancedServerList
```
////
///
/// tab | :octicons-git-merge-24: Velocity
//// tab | Softdepend (File)
```json title="velocity-plugin.json"
{
"id": "myplugin",
"name": "MyPlugin",
"version": "1.0.0",
"authors": [
"author"
],
"main": "com.example.plugin.ExamplePlugin",
"dependencies": [
{
"id": "advancedserverlist",
"optional": true
}
]
}
```
////
//// tab | Depend (File)
```json title="velocity-plugin.json"
{
"id": "myplugin",
"name": "MyPlugin",
"version": "1.0.0",
"authors": [
"author"
],
"main": "com.example.plugin.ExamplePlugin",
"dependencies": [
{
"id": "advancedserverlist",
"optional": false // Default, not required
}
]
}
```
////
//// tab | Softdepend (Annotation)
```java title="MyPlugin.java"
@Plugin(
id = "myplugin",
name = "MyPlugin",
version = "1.0.0",
authors = {"author"},
dependencies = {
@Dependency(
id = "advancedserverlist",
optional = true
)
}
)
public class MyPlugin {
// ...
}
```
////
//// tab | Depend (Annotation)
```java title="MyPlugin.java"
@Plugin(
id = "myplugin",
name = "MyPlugin",
version = "1.0.0",
authors = {"author"},
dependencies = {
@Dependency(
id = "advancedserverlist",
optional = false // Default, not required
)
}
)
public class MyPlugin {
// ...
}
```
////
///
### 4. You're done!
Your plugin should now hook into AdvancedServerList and register its own custom placeholders to use.
## Listening for events
<!-- admo:info This requires the platform specific dependencies -->
AdvancedServerList provides an Event that your plugin can listen for.
The event is called `PreServerListSetEvent` and provides the following methods to use:
- [`getEntry()`][getentry] - Gets the currently set [`ProfileEntry`][profileentry].
- [`setEntry(ProfileEntry)`][setentry] - Sets a new [`ProfileEntry`][profileentry] to use.
- [`isCancelled()`][iscancelled] - Gets the current cancelled state of the event.
- [`setCancelled(boolean)`][setcancelled] - Sets the current cancelled state.
Setting the event's cancelled state to true will result in AdvancedServerList not altering the Server list.
Please check the server/proxy's documentation on how to listen for events with your plugin.
[getentry]: reference/api/ch.andre601.advancedserverlist.api/events/genericserverlistevent.md#getentry()
[setentry]: reference/api/ch.andre601.advancedserverlist.api/events/genericserverlistevent.md#setentry(profileentry)
[iscancelled]: reference/api/ch.andre601.advancedserverlist.api/events/genericserverlistevent.md#iscancelled()
[setcancelled]: reference/api/ch.andre601.advancedserverlist.api/events/genericserverlistevent.md#setcancelled(boolean)
[profileentry]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/index.md
### ProfileEntry
The ProfileEntry class has been moved to the API in v2 allowing you to create your own versions using the available Builder class.
The ProfileEntry record is the core class used within the `PreServerListSetEvent`. It sets what values (MOTD, Favicon, Players, etc.) should be displayed.
Note that the record is - by nature - immutable and that the [`Builder`][builder] class should be used to create a new ProfileEntry instance to use.
This class contains values from a Server List Profile file. The values can either be from a `profiles` list entry, one of the global options in the file, or a mix of both, depending on what options are present.
You can create a new entry or copy an existing one (i.e. from the [`PreServerListSetEvent`](#events)) to modify and use in the server list by setting it in the aforementioned `PreServerListSetEvent`.
A convenience method exists to create a `Builder` instance from an existing `ProfileEntry` in case you only want to alter certain options while everything else unchanged.
This allows you to customize the Server list using your plugin. Just keep in mind that other plugins may also do the same, overriding your changes.
[builder]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/builder.md
+10
View File
@@ -0,0 +1,10 @@
---
template: redirect.html
location: https://docs.andre601.ch/asl-api
title: Javadocs
icon: octicons/link-external-24
---
<!-- Comment to trigger proper build -->
@@ -112,16 +112,67 @@ methods:
type:
name: 'Builder'
type: 'object'
- name: 'setExtraPlayers'
- name: 'setMaxPlayersEnabled'
description: |
Sets whether the max players feature should be enabled.<br>
<br>
Set to <a href="../../objects/nullbool/#not_set"><code>NullBool.NOT_SET</code></a> to not set this.
returns: 'This Builder after the NullBool has been set. Useful for chaining.'
parameters:
- name: 'maxPlayersEnabled'
description: 'Whether the extra players feature should be enabled or not.'
type: NullBool
attributes:
- notnull
throws:
- name: 'IllegalArgumentException'
description: 'Thrown by the <code>CheckUtil</code> in case <code>null</code> has been provided as parameter.'
type:
name: 'Builder'
type: 'object'
- name: 'setExtraPlayerCount'
description: |
Sets the number of players to add to the online players to use as the new max players value.<br>
This option has no effect when <a href="../#extraplayersenabled()"><code>extraPlayersEnabled()</code></a> is set to <a href="../../objects/nullbool/#false"><code>NullBool.FALSE</code></a>.<br>
This option has no effect when <a href="../#extraplayersenabled()"><code>extraPlayersEnabled</code></a> is set to <a href="../../objects/nullbool/#false"><code>NullBool.FALSE</code></a> or <a href="../../objects/nullbool/#not_set"><code>NullBool.NOT_SET</code></a>.<br>
<br>
Set this to <code>null</code> to not alter the max player count. Alternatively, set <a href="#setextraplayersenabled(nullbool)"><code>setExtraPlayersEnabled(NullBool)</code></a> to <a href="../../objects/nullbool/#false"><code>NullBool.FALSE</code></a>.
returns: 'This Builder after the extra player count has been set. Useful for chaining.'
parameters:
- name: 'extraPlayersCount'
description: 'The number of extra players to use.'
description: 'The number of extra players to add.'
type: Integer
attributes:
- nullable
deprecated: 'Typo in the name. Use <a href="#setextraplayerscount(integer)">setExtraPlayersCount(Integer)</a> instead.'
type:
name: 'Builder'
type: 'object'
- name: 'setExtraPlayersCount'
description: |
Sets the number of players to add to the online players to use as the new max players value.<br>
This option has no effect when <a href="../#extraplayersenabled()"><code>extraPlayersEnabled</code></a> is set to <a href="../../objects/nullbool/#false"><code>NullBool.FALSE</code></a> or <a href="../../objects/nullbool/#not_set"><code>NullBool.NOT_SET</code></a>.<br>
<br>
Set this to <code>null</code> to not alter the max player count. Alternatively, set <a href="#setextraplayersenabled(nullbool)"><code>setExtraPlayersEnabled(NullBool)</code></a> to <a href="../../objects/nullbool/#false"><code>NullBool.FALSE</code></a>.
returns: 'This Builder after the extra player count has been set. Useful for chaining.'
parameters:
- name: 'extraPlayersCount'
description: 'The number of extra players to add.'
type: Integer
attributes:
- nullable
type:
name: 'Builder'
type: 'object'
- name: 'setMaxPlayersCount'
description: |
Sets the number of max players allowed to join this server.<br>
This option has no effect when <a href="../#maxplayersenabled()"><code>maxPlayersEnabled</code></a> is set to <a href="../../objects/nullbool/#false"><code>NullBool.FALSE</code></a> or <a href="../../objects/nullbool/#not_set"><code>NullBool.NOT_SET</code></a>.<br>
<br>
Set this to <code>null</code> to not alter the max player count. Alternatively, set <a href="#setmaxplayersenabled(nullbool)"><code>setMaxPlayersEnabled(NullBool)</code></a> to <a href="../../objects/nullbool/#false"><code>NullBool.FALSE</code></a>.
returns: 'This Builder after the extra player count has been set. Useful for chaining.'
parameters:
- name: 'maxPlayersCount'
description: 'The number of max players to set.'
type: Integer
attributes:
- nullable
@@ -37,11 +37,21 @@ constructors:
type: NullBool
attributes:
- notnull
- name: 'maxPlayersEnabled'
description: 'Whether the max players option should be enabled.'
type: NullBool
attributes:
- notnull
- name: 'extraPlayersCount'
description: 'The number to add to the online players for the max players number.'
type: Integer
attributes:
- nullable
- name: 'maxPlayersCount'
description: 'The number to use for the max players count.'
type: Integer
attributes:
- nullable
seealso:
- name: 'ProfileEntry.Builder'
link: './builder/'
@@ -61,9 +71,11 @@ methods:
<li><a href="#players()"><code>players</code></a>: Empty List</li>
<li><a href="#playercounttext()"><code>playerCountText</code></a>: Empty String</li>
<li><a href="#favicon()"><code>favicon</code></a>: Empty String</li>
<li><a href="#hideplayersenabled()"><code>hidePlayersEnabled</code></a>: <a href="../../objects/nullbool/"><code>NullBool.NOT_SET</code></a></li>
<li><a href="#extraplayersenabled()"><code>extraPlayersEnabled</code></a>: <a href="../../objects/nullbool/"><code>NullBool.NOT_SET</code></a></li>
<li><a href="#hideplayersenabled()"><code>hidePlayersEnabled</code></a>: <a href="../../objects/nullbool/#not_set"><code>NullBool.NOT_SET</code></a></li>
<li><a href="#extraplayersenabled()"><code>extraPlayersEnabled</code></a>: <a href="../../objects/nullbool/#not_set"><code>NullBool.NOT_SET</code></a></li>
<li><a href="#maxplayersenabled()"><code>maxPlayersEnabled</code></a>: <a href="../../objects/nullbool/#not_set"><code>NullBoo.NOT_SET</code></a></li>
<li><a href="#extraplayerscount()"><code>extraPlayersCount</code></a>: <code>null</code></li>
<li><a href="#maxplayerscount()"><code>maxPlayersCount</code></a>: <code>null</code></li>
</ul>
returns: 'New ProfileEntry instance with empty/null values defined'
attributes:
@@ -142,6 +154,15 @@ methods:
name: 'NullBool'
type: 'object'
link: '../../objects/nullbool/'
- name: 'maxPlayersEnabled'
description: |
Whether the max players feature should be used or not.<br>
To get the actual boolean value, append <a href="../../objects/nullbool/#getordefault()"><code>getOrDefault(boolean)</code></a>.
returns: 'Whether the max players feature should be used or not.'
type:
name: 'NullBool'
type: 'object'
link: '../../objects/nullbool/'
- name: 'extraPlayersCount'
description: 'Gets the currently set number of extra players to use by this ProfileEntry. May be <code>null</code>.'
returns: 'Possibly-null integer number of extra players used by this ProfileEntry.'
@@ -150,6 +171,14 @@ methods:
type:
name: 'Integer'
type: 'object'
- name: 'maxPlayersCount'
description: 'Gets the currently set number of max players of this ProfileEntry.'
returns: 'The current number of max players used by this ProfileEntry.'
attributes:
- nullable
type:
name: 'Integer'
type: 'object'
- name: 'isInvalid'
description: |
Whether this ProfileEntry is considered invalid or not.<br>
+18 -9
View File
@@ -5,6 +5,8 @@ The Reference docs follow a specific mixture of manually created and auto-genera
A page may look something like this:
```markdown
---
template: api-doc.html
constructors:
- name: 'Constructor'
description: 'Creates a new instance of this class.'
@@ -25,7 +27,7 @@ An example class to show how the page structure may look like.
## custom HTML tags
There is a collection of custom HTML tags that are used to render specific text in certain styles.
Below is a list of all custom tags. Note that these tags only render on the actual site and not within the repository.
Below is a list of all custom tags. Note that these tags only render on the actual site and not within the repository when viewing the source.
- `<api__class></api__class>`: <api__class></api__class>
- `<api__interface></api__interface>`: <api__interface></api__interface>
@@ -36,16 +38,17 @@ Below is a list of all custom tags. Note that these tags only render on the actu
- `<api__final></api__final>`: <api__final></api__final>
- `<api__notnull></api__notnull>`: <api__notnull></api__notnull>
- `<api__nullable></api__nullable>`: <api__nullable></api__nullable>
- `<api__deprecated></api__deprecated>`: <api__deprecated></api__deprecated>
In addition are there two classes used within `span` tags to colour the text, to indicate their type:
- `<span class="api-type__object">Object</span>`: <span class="api-type__object">Object</span>
- `<span class="api-type__primitive">Object</span>`: <span class="api-type__primitive">Primitive</span>
- `<span class="api-type__primitive">primitive</span>`: <span class="api-type__primitive">primitive</span>
## Auto-generated content
The page template used checks for specific YAML frontmatter in the page to include other templates.
These templates pull the data from the YAML frontmatter to generate the page content which is then appendet to the already existing page content.
A page template is used to auto-generate the page content based on available YAML frontmatter.
Depending on the frontmatter available will the template call a jinja2 Macro to generate a Summary and Detailed info on the page for the respective frontmatter data.
There are 5 frontmatter options, each following a specific structure:
@@ -67,10 +70,11 @@ constructors:
type: '<string>'
attributes:
- '<string>'
deprecated: '<string>'
throws:
- name: '<string>'
description: '<string>'
seealos:
seealso:
- name: '<string>'
link: '<string>'
```
@@ -84,6 +88,7 @@ constructors:
- `description` - Description of the parameter.
- `type` - The type this parameter is.
- `attributes` - List of attributes (i.e. nullability) to display. The provided values will be turned into `<api__{name}></api__{name}>` tags that will be prependet to the parameter name.
- `deprecated` - Adds a notice about the deprecation of this Constructor in the form of a deprecation label and a `deprecated` section with the provided `<string>` as explanation.
- `throws` - List of possible throws to display.
- `name` - Name of the throw to display.
- `description` - Description of the throw.
@@ -115,6 +120,7 @@ enums:
- name: '<string>'
description: '<string>'
type: '<string>'
deprecated: '<string>'
seealso:
- name: '<string>'
link: '<string>'
@@ -122,9 +128,10 @@ enums:
**Options:**
- `name` - The name to display for the Constructor summary and detail. This should include any parameters the Constructor has, but without any parameter name.
- `description` - The description to display for the Constructor.
- `name` - The name to display for the Enum summary and detail. This should include any parameters the Enum has, but without any parameter name.
- `description` - The description to display for the Enum.
- `type` - The return type to display. Will default to `{{ page.title }}` if not set.
- `deprecated` - Adds a notice about the deprecation of this Enum in the form of a deprecation label and a `deprecated` section with the provided `<string>` as explanation.
- `seealso` - List of "See also" text to display.
- `name` - Name of the See also link.
- `link` - Link (Relative, absolute or URL) to use for the See also text.
@@ -148,6 +155,7 @@ methods:
attributes:
- '<string>'
returns: '<string>'
deprecated: '<string>'
throws:
- name: '<string>'
description: '<string>'
@@ -158,8 +166,8 @@ methods:
**Options:**
- `name` - The name to display for the Constructor summary and detail. This should include any parameters the Constructor has, but without any parameter name.
- `description` - The description to display for the Constructor.
- `name` - The name to display for the Method summary and detail. This should include any parameters the Method has, but without any parameter name.
- `description` - The description to display for the Method.
- `type` - Options for object type to display.
- `name` - Displayed name of the object.
- `type` - Object type. Can be either `object` or `primitive` which would be used in a class name for styling.
@@ -171,6 +179,7 @@ methods:
- `type` - The type this parameter is.
- `attributes` - List of attributes (i.e. nullability) to display. The provided values will be turned into `<api__{name}></api__{name}>` tags that will be prependet to the parameter name.
- `returns` - Possible return values.
- `deprecated` - Adds a notice about the deprecation of this Method in the form of a deprecation label and a `deprecated` section with the provided `<string>` as explanation.
- `throws` - List of possible throws to display.
- `name` - Name of the throw to display.
- `description` - Description of the throw.
+10
View File
@@ -0,0 +1,10 @@
---
template: redirect.html
location: https://github.com/Andre601/asl-api
title: Source Code
icon: octicons/mark-github-16
---
<!-- Comment to trigger proper build -->
Loaded 100 of 153 files, more files were not shown because too many files have changed in this diff. Show more