mirror of
https://codeberg.org/Andre601/AdvancedServerList.git
synced 2026-11-05 09:00:15 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8459eee57d | ||
|
|
f5cebf42ab | ||
|
|
731bdeba7d | ||
|
|
d14cda243a | ||
|
|
0a98aad138 | ||
|
|
1249a08264 | ||
|
|
c0414a5962 | ||
|
|
9cc4d4bb36 | ||
|
|
338358a2ab | ||
|
|
805ba83bb6 | ||
|
|
0f646a8f8d | ||
|
|
2519f09f6f | ||
|
|
60bca9e3d7 | ||
|
|
da8f72fc50 | ||
|
|
c42d4b8967 | ||
|
|
0110854ae4 | ||
|
|
d6d5952cbc | ||
|
|
f9d961cae7 | ||
|
|
a387feea23 | ||
|
|
359c58163b | ||
|
|
0892f5cd1d | ||
|
|
452a7e6dcf | ||
|
|
162dd10a73 | ||
|
|
35120c5364 | ||
|
|
6c828171d2 | ||
|
|
dcc51f8458 | ||
|
|
1287ca62fe | ||
|
|
1ff439fa95 | ||
|
|
ed0f832b2f | ||
|
|
b8e6b2acc6 | ||
|
|
fba32c91c5 | ||
|
|
6505ded12b | ||
|
|
53088affcb | ||
|
|
9c030764fa | ||
|
|
d5d58f1eea | ||
|
|
7181092821 | ||
|
|
fc5ee4f242 | ||
|
|
6e74c4fb14 | ||
|
|
f6a27342e6 | ||
|
|
38b50df2c9 | ||
|
|
db93816e55 | ||
|
|
244c2440fc | ||
|
|
8e2c644669 | ||
|
|
a68809ab31 | ||
|
|
4b4fd80abe | ||
|
|
48ea128267 | ||
|
|
68e5795618 | ||
|
|
1aa20e4196 | ||
|
|
6db25c8f9c | ||
|
|
0ef3db752d | ||
|
|
1a26f5ad34 | ||
|
|
17a5574be7 | ||
|
|
c7bfb8a736 | ||
|
|
7a756c3b98 | ||
|
|
1539e1c3c0 | ||
|
|
a86872c021 | ||
|
|
7d12499f39 | ||
|
|
455434b5f3 | ||
|
|
b66251ab20 | ||
|
|
4a1dfa5cb4 | ||
|
|
1efd65e16c | ||
|
|
908da9cd32 | ||
|
|
e8a30c6ef7 | ||
|
|
df164c104f | ||
|
|
acdf6f6e9a | ||
|
|
f52a63a8f1 | ||
|
|
6a92cb3a16 | ||
|
|
1175451753 | ||
|
|
5c4130411b | ||
|
|
05727eeec5 | ||
|
|
10af949abc | ||
|
|
9851347e74 | ||
|
|
c3e01c8b9c | ||
|
|
a646d9e998 | ||
|
|
3c50a30d4a | ||
|
|
4328ad6b44 | ||
|
|
34b0555508 | ||
|
|
c92cd0058b | ||
|
|
2cfe8b8a27 | ||
|
|
6530fed704 | ||
|
|
7efb203e7b | ||
|
|
1a34376100 | ||
|
|
ec1aa5b393 | ||
|
|
9683d3c001 | ||
|
|
db60545fcc | ||
|
|
392495ef63 | ||
|
|
903764b234 | ||
|
|
72329ed1e4 | ||
|
|
c516b56053 | ||
|
|
5e4295fbfb | ||
|
|
b140c0aa32 | ||
|
|
8f7b293541 | ||
|
|
6f878164c5 | ||
|
|
a16801ff56 | ||
|
|
65a89cf762 | ||
|
|
27d4ada179 | ||
|
|
574edfb246 | ||
|
|
7b7aad9d4e | ||
|
|
c5c9ed8109 | ||
|
|
58fea4090d | ||
|
|
cd0aad6ec1 | ||
|
|
fa45844434 | ||
|
|
c4e2a144b5 | ||
|
|
7fe93c7021 | ||
|
|
1d413a5c2a | ||
|
|
51db52dbdd | ||
|
|
4ade528188 | ||
|
|
64ba48a7c7 | ||
|
|
ac4edb2b97 | ||
|
|
3ea000c98b | ||
|
|
746bef13e1 | ||
|
|
355ab73546 | ||
|
|
67170c70e0 | ||
|
|
f99c2df4e8 | ||
|
|
212ec04fb8 | ||
|
|
89c6089101 | ||
|
|
87bce39d9a | ||
|
|
18900547a0 | ||
|
|
5df2e05a14 | ||
|
|
d4e4173cc3 | ||
|
|
562ad481c5 | ||
|
|
a0ee2a4322 | ||
|
|
2c92efdb43 | ||
|
|
555dc9d6a5 | ||
|
|
27742c5e1b | ||
|
|
280aeb8d2e | ||
|
|
92a868f0fa | ||
|
|
189ac5e09b | ||
|
|
833cb81d65 | ||
|
|
ab09422da5 | ||
|
|
64cad6dc26 | ||
|
|
ce78b493f4 | ||
|
|
c43048ea3f | ||
|
|
6d4d1600ab | ||
|
|
f114e99b9b | ||
|
|
3d587bc86d | ||
|
|
bd8c6be7c6 | ||
|
|
b5d5d508e2 | ||
|
|
3001b65fe8 | ||
|
|
c82771db59 | ||
|
|
9880836c25 | ||
|
|
f12ae28722 | ||
|
|
42b0f0e94f | ||
|
|
0a4b872051 | ||
|
|
b1322105ed | ||
|
|
831ca57fbb | ||
|
|
6502639cd3 | ||
|
|
5059b80db2 | ||
|
|
ecdaf72963 | ||
|
|
28e2ca69ed | ||
|
|
9cad78b6e4 | ||
|
|
af8654666b | ||
|
|
6cd474b35d | ||
|
|
3802ab556c | ||
|
|
3a520eeaf0 | ||
|
|
204f43c112 | ||
|
|
fc8ed8e49e | ||
|
|
56082c308b | ||
|
|
205e563095 | ||
|
|
5b01940c60 | ||
|
|
cbb087e3d1 | ||
|
|
524b926244 | ||
|
|
4059bbfe93 | ||
|
|
9b0b69a4f4 | ||
|
|
10a82eb951 | ||
|
|
690f7dfaf0 | ||
|
|
6a22d20b3a | ||
|
|
b1072bb1fa | ||
|
|
d20da91bab | ||
|
|
17e9692028 | ||
|
|
45dc8a5fe6 | ||
|
|
a237ac1ce4 | ||
|
|
27e66a16b9 | ||
|
|
8f98846bc3 | ||
|
|
bbcab59845 | ||
|
|
3130e07070 | ||
|
|
7bc61ddf4d | ||
|
|
53d15a9011 | ||
|
|
8718e4a0ae | ||
|
|
06a49956af | ||
|
|
38ec131b69 | ||
|
|
1bdaa61dd9 | ||
|
|
080d5055c4 | ||
|
|
423b363964 | ||
|
|
6b9abfccfc | ||
|
|
f589a8da35 | ||
|
|
465581306f | ||
|
|
6b2919961b | ||
|
|
adb6e797b2 | ||
|
|
b410b9438f | ||
|
|
c1d5b4efa9 | ||
|
|
4785dd127e | ||
|
|
9e8e2f7e74 | ||
|
|
c14dfe0f3a | ||
|
|
ed92e7002c | ||
|
|
8f93d9732c | ||
|
|
96f8fa5860 | ||
|
|
bfb857bd5c | ||
|
|
5fe3b5811c | ||
|
|
2a7eff0092 | ||
|
|
1907f5d47e | ||
|
|
aa92350b52 | ||
|
|
869b9bd3b7 | ||
|
|
fe31dcf0a4 | ||
|
|
6b44438f52 | ||
|
|
6b0c654f41 | ||
|
|
c28ff3a891 | ||
|
|
f424b41c3b | ||
|
|
b5f901d8f5 | ||
|
|
29d52492fc | ||
|
|
2d6af20bdc | ||
|
|
59c913ecf8 | ||
|
|
4a50beb4e0 | ||
|
|
c099127272 | ||
|
|
15974b5c54 | ||
|
|
483afe63c4 | ||
|
|
f0cb458a34 | ||
|
|
2c547cd6d0 | ||
|
|
e7282b4a97 |
No files matched your search
@@ -2,16 +2,6 @@ name: 'Deploy Site (Push)'
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- 'mkdocs.yml'
|
||||
- 'requirements.txt'
|
||||
- '.github/workflows/docs-deploy.yml'
|
||||
branches:
|
||||
- master
|
||||
tags-ignore:
|
||||
- '**'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -34,11 +24,11 @@ jobs:
|
||||
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
|
||||
@@ -49,10 +39,11 @@ jobs:
|
||||
- name: Build docs
|
||||
run: mkdocs build
|
||||
- name: Configure GitHub Pages
|
||||
uses: actions/configure-pages@v3
|
||||
uses: actions/configure-pages@v4
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v2
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: 'site/'
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: actions/deploy-pages@v2
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
@@ -2,3 +2,4 @@
|
||||
/.idea/
|
||||
/**/dependency-reduced-pom.xml
|
||||
/**/target/
|
||||
/**/__pycache__/
|
||||
@@ -4,12 +4,10 @@ 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: gh_token
|
||||
target: github_api_token
|
||||
- source: modrinth_api_token
|
||||
target: modrinth_api_token
|
||||
- source: hangar_api_token
|
||||
@@ -28,8 +26,8 @@ steps:
|
||||
settings:
|
||||
base_url: https://codeberg.org
|
||||
files:
|
||||
- "bukkit/target/AdvancedServerList-*.jar"
|
||||
- "bungeecord/target/AdvancedServerList-*.jar"
|
||||
- "paper/target/AdvancedServerList-*.jar"
|
||||
- "velocity/target/AdvancedServerList-*.jar"
|
||||
api_key:
|
||||
from_secret: CB_TOKEN
|
||||
@@ -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
|
||||
@@ -1,45 +0,0 @@
|
||||
platform: linux/amd64
|
||||
|
||||
when:
|
||||
event:
|
||||
- cron
|
||||
- manual
|
||||
branch:
|
||||
- master
|
||||
|
||||
steps:
|
||||
#renovateDryRun:
|
||||
# image: renovate/renovate
|
||||
# pull: true
|
||||
# commands:
|
||||
# - renovate $${CI_REPO}
|
||||
# environment:
|
||||
# RENOVATE_PLATFORM: gitea
|
||||
# RENOVATE_ENDPOINT: https://codeberg.org
|
||||
# LOG_LEVEL: debug
|
||||
# RENOVATE_DRY_RUN: full
|
||||
# secrets:
|
||||
# - source: rb_token
|
||||
# target: renovate_token
|
||||
# - source: git_author
|
||||
# target: renovate_git_author
|
||||
# when:
|
||||
# - event: push
|
||||
renovate:
|
||||
image: renovate/renovate
|
||||
pull: true
|
||||
commands:
|
||||
- renovate $${CI_REPO}
|
||||
environment:
|
||||
RENOVATE_PLATFORM: gitea
|
||||
RENOVATE_ENDPOINT: https://codeberg.org
|
||||
LOG_LEVEL: debug
|
||||
secrets:
|
||||
- source: rb_token
|
||||
target: renovate_token
|
||||
- source: gh_renovate_token
|
||||
target: github_com_token
|
||||
when:
|
||||
- event: cron
|
||||
cron: renovate
|
||||
- event: manual
|
||||
@@ -1,21 +1,21 @@
|
||||
# AdvancedServerList
|
||||
|
||||
AdvancedServerList is a plugin that allowys you to customize your server's MOTD, favicon, Player count text and player count hover displayed in a player's multiplayer server list based on conditions and priorities.
|
||||
AdvancedServerList is a plugin that allows 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>
|
||||
@@ -30,29 +30,33 @@ AdvancedServerList is a plugin that allowys you to customize your server's MOTD,
|
||||
</a>
|
||||
|
||||
## What is a Server List Profile?
|
||||
|
||||
A Server List Profile refers to a YAML file located in the plugin's `profiles` directory.
|
||||
It allows you to configure specific aspects of the server display in the MC-Client's multiplayer server list, such as the MOTD, player count text, player count hover or Favicon.
|
||||
|
||||
> [*Read More*][profiles]
|
||||
|
||||
### Conditions
|
||||
Thanks to conditions can you determine when a profile should be displayed in the player’s server list, to allow displaying specific text (i.e. a warning when they are using an outdated version).
|
||||
|
||||
When multiple profiles exist that have valid conditions will the one with the highest priority (Higher number = higher priority) be selected. Having no conditions makes the profile automatically return true.
|
||||
Thanks to conditions can you determine when a profile should be displayed in the player's server list, to allow displaying specific text (i.e. a warning when they are using an outdated version).
|
||||
|
||||
When multiple profiles exist that have valid conditions will the one with the highest priority (Higher number = higher priority) be selected. Having no conditions makes it automatically true.
|
||||
|
||||
> [*Read More*][conditions]
|
||||
|
||||
### Placeholders
|
||||
Placeholders can be used within conditions to further customize them. They can also be used in any other text option (motd, playerCount and players) to display their respective values.
|
||||
|
||||
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][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 on the server (not proxy) for that.
|
||||
|
||||
If you're a plugin dev can you even add your own custom placeholders through AdvancedServerList's own API.
|
||||
|
||||
> [*Read More*][placeholders]
|
||||
|
||||
### Formatting
|
||||
|
||||
The plugin uses the MiniMessage format for a consistent, easy way of formatting your text.
|
||||
Only certain options are usable for each option. As an example does motd support HEX colours and gradients, while the other options only support default colour codes.
|
||||
|
||||
@@ -60,13 +64,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] | BungeeCord, Velocity | No |
|
||||
| [Maintenance] | All | No |
|
||||
All listed dependencies are optional.
|
||||
|
||||
| Dependency | Platforms |
|
||||
|-------------------|----------------------|
|
||||
| [PlaceholderAPI] | Paper |
|
||||
| [ViaVersion] | Paper |
|
||||
| [PAPIProxyBridge] | BungeeCord, Velocity |
|
||||
| [Maintenance] | All |
|
||||
|
||||
## Statistics
|
||||
|
||||
@@ -84,6 +89,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 +102,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
|
||||
|
||||
-75
@@ -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));
|
||||
}
|
||||
}
|
||||
-62
@@ -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("======================================================================================");
|
||||
}
|
||||
}
|
||||
-203
@@ -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);
|
||||
}
|
||||
}
|
||||
-84
@@ -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));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+7
-17
@@ -67,33 +67,33 @@
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.20-R0.1</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.20-R0.1</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.14.0</version>
|
||||
<version>4.15.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-text-minimessage</artifactId>
|
||||
<version>4.14.0</version>
|
||||
<version>4.15.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-platform-bungeecord</artifactId>
|
||||
<version>4.3.0</version>
|
||||
<version>4.3.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.11.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>
|
||||
|
||||
+1
-1
@@ -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(){
|
||||
|
||||
+17
-2
@@ -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
|
||||
|
||||
+9
-3
@@ -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;
|
||||
|
||||
@@ -81,6 +85,8 @@ public class BungeeServerPlaceholders extends PlaceholderProvider{
|
||||
|
||||
if(args.length == 2){
|
||||
ServerInfo info = proxy.getServers().get(args[1]);
|
||||
if(info == null)
|
||||
yield null;
|
||||
|
||||
yield String.valueOf(((InetSocketAddress)info.getSocketAddress()).getHostString());
|
||||
}
|
||||
|
||||
+15
-16
@@ -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.2</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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+43
-4
@@ -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,32 +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;
|
||||
}
|
||||
|
||||
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))
|
||||
@@ -98,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))
|
||||
@@ -111,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);
|
||||
@@ -127,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");
|
||||
}
|
||||
}
|
||||
+42
-3
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+107
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+78
@@ -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;
|
||||
}
|
||||
}
|
||||
+28
@@ -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{}
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* 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_IGNORE_CASE, "=~"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL, "="))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL_IGNORE_CASE, "~"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.NOT_EQUAL, "!="))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.NOT_EQUAL_IGNORE_CASE, "!~"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.STARTS_WITH, "|-"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.ENDS_WITH, "-|"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.CONTAINS, "<_"))
|
||||
.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.STARTS_WITH, Operator.of(25, ExpressionTemplates::startsWith))
|
||||
.operator(DefaultTokens.ENDS_WITH, Operator.of(25, ExpressionTemplates::endsWith))
|
||||
.operator(DefaultTokens.CONTAINS, Operator.of(25, ExpressionTemplates::contains))
|
||||
.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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* 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 startsWith(ToStringExpression a, ToStringExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return a.evaluate().startsWith(b.evaluate());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression endsWith(ToStringExpression a, ToStringExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return a.evaluate().endsWith(b.evaluate());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression contains(ToStringExpression a, ToStringExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return a.evaluate().contains(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();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+49
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+56
@@ -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);
|
||||
}
|
||||
+54
@@ -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);
|
||||
}
|
||||
+44
@@ -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;
|
||||
}
|
||||
}
|
||||
+133
@@ -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() + "\"");
|
||||
}
|
||||
}
|
||||
+51
@@ -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;
|
||||
}
|
||||
}
|
||||
+51
@@ -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;
|
||||
}
|
||||
}
|
||||
+43
@@ -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;
|
||||
}
|
||||
}
|
||||
+71
@@ -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;
|
||||
}
|
||||
}
|
||||
+43
@@ -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;
|
||||
}
|
||||
}
|
||||
+44
@@ -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;
|
||||
}
|
||||
}
|
||||
+10
-13
@@ -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);
|
||||
}
|
||||
+62
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
+111
@@ -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);
|
||||
}
|
||||
}
|
||||
+40
@@ -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;
|
||||
}
|
||||
}
|
||||
+40
@@ -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;
|
||||
}
|
||||
}
|
||||
+43
@@ -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());
|
||||
}
|
||||
}
|
||||
+43
@@ -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());
|
||||
}
|
||||
}
|
||||
+43
@@ -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());
|
||||
}
|
||||
}
|
||||
+40
@@ -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;
|
||||
}
|
||||
}
|
||||
+40
@@ -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;
|
||||
}
|
||||
}
|
||||
+40
@@ -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;
|
||||
}
|
||||
}
|
||||
+38
@@ -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;
|
||||
}
|
||||
}
|
||||
+38
@@ -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;
|
||||
}
|
||||
}
|
||||
+38
@@ -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;
|
||||
}
|
||||
}
|
||||
+77
@@ -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;
|
||||
}
|
||||
}
|
||||
+58
@@ -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);
|
||||
}
|
||||
}
|
||||
+39
@@ -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();
|
||||
}
|
||||
+422
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* 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 startsWith(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new StartsWith(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate endsWith(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new EndsWith(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate contains(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new Contains(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 StartsWith extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
private StartsWith(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.startsWith(a.instantiateWithStringResult(), b.instantiateWithStringResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class EndsWith extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
private EndsWith(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.endsWith(a.instantiateWithStringResult(), b.instantiateWithStringResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Contains extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
private Contains(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.contains(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());
|
||||
}
|
||||
}
|
||||
}
|
||||
+42
@@ -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;
|
||||
}
|
||||
}
|
||||
+50
@@ -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;
|
||||
|
||||
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 STARTS_WITH = new Token("STARTS_WITH");
|
||||
public static final Token ENDS_WITH = new Token("ENDS_WITH");
|
||||
public static final Token CONTAINS = new Token("CONTAINS");
|
||||
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");
|
||||
}
|
||||
+40
@@ -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;
|
||||
}
|
||||
}
|
||||
+42
@@ -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;
|
||||
}
|
||||
}
|
||||
+40
@@ -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;
|
||||
}
|
||||
}
|
||||
+11
-4
@@ -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;
|
||||
}
|
||||
}
|
||||
+53
@@ -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()));
|
||||
}
|
||||
}
|
||||
+55
@@ -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;
|
||||
}
|
||||
}
|
||||
+61
@@ -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;
|
||||
}
|
||||
}
|
||||
+50
@@ -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;
|
||||
}
|
||||
}
|
||||
+62
@@ -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;
|
||||
}
|
||||
}
|
||||
+13
-22
@@ -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);
|
||||
}
|
||||
+24
-1
@@ -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);
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ public class ProfileManager{
|
||||
if(profile.isInvalidProfile())
|
||||
continue;
|
||||
|
||||
if(profile.evalConditions(player, server))
|
||||
if(profile.evalConditions(core.getExpressionEngine(), core.getPlugin().getPluginLogger(), player, server))
|
||||
return profile;
|
||||
}
|
||||
|
||||
|
||||
@@ -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}
|
||||
@@ -6,6 +6,15 @@
|
||||
#
|
||||
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).
|
||||
|
||||
@@ -23,4 +23,5 @@
|
||||
#
|
||||
#
|
||||
|
||||
version=${plugin.version}
|
||||
version=${plugin.version}
|
||||
config-version=${plugin.config.version}
|
||||
+26
-18
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#
|
||||
# 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 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)
|
||||
|
||||
# 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>",
|
||||
])
|
||||
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# A simple hook that replaces any appearances of \| with just |.
|
||||
#
|
||||
# There is an inconsistency between GitHub flavourited Markdown and Python Markdown
|
||||
# where the former treats | as part of a table, even if it is inside inline code
|
||||
# causing unwanted table rendering.
|
||||
#
|
||||
# The only way to prevent this is to escape it by prefixing it with a back slash (\).
|
||||
# Unfortunately does this cause issues on Python-Markdown, as it renders inline code
|
||||
# content as-is without special treatments whatsoever, meaning that `\|` will be
|
||||
# rendered as <code>\|</code> in the end.
|
||||
#
|
||||
# Using this hook, `\|` is being turned into `|` before further processing, resulting
|
||||
# in <code>|</code> being rendered in the end, while preserving proper table rendering
|
||||
# on GitHub and co.
|
||||
#
|
||||
import re
|
||||
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
from mkdocs.structure.files import File, Files
|
||||
from mkdocs.structure.pages import Page
|
||||
|
||||
def on_page_markdown(
|
||||
markdown: str, *, page: Page, config: MkDocsConfig, files: Files
|
||||
):
|
||||
return re.sub(r"\\\|","|",markdown)
|
||||
@@ -149,7 +149,7 @@
|
||||
</h3>
|
||||
|
||||
{% if detail.deprecated %}
|
||||
<div class="admonition danger">
|
||||
<div class="admonition deprecated">
|
||||
<div class="admonition-title">Deprecation Warning</div>
|
||||
<p>
|
||||
{{ detail.deprecated }}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
nav:
|
||||
- Home: index.md
|
||||
- getting-started
|
||||
- commands
|
||||
- profiles
|
||||
- examples
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
+21
-12
@@ -7,25 +7,34 @@ icon: octicons/log-24
|
||||
This page lists the recent changes made towards the AdvancedServerListAPI.
|
||||
They are ordered newest to oldest.
|
||||
|
||||
## v3.1.0
|
||||
## v3.1.0 { #v3.1.0 }
|
||||
|
||||
### :octicons-plus-circle-24:{ .changelog-added title="Added" } Added { #v3.1.0-added }
|
||||
|
||||
- New getters in `ProfileEntry`:
|
||||
- `maxPlayersEnabled()` - Returns the value for `playerCount -> maxPlayers -> enabled` as `NullBool`
|
||||
- `maxPlayersCount()` - Returns the value of `playerCount -> maxPlayers -> amount` as nullable `Integer`
|
||||
- New setters in `ProfileEntry.Builder`:
|
||||
- `setMaxPlayersEnabled(NullBool)` - Sets whether the max players feature is enabled or not.
|
||||
- `setMaxPlayersCount(Integer)` - Sets the number to use for the max players count.
|
||||
- `setExtraPlayersCount(Integer)` - Replacement for [deprecated `setExtraPlayerCount(Integer)` method](#v3.1.0-deprecated).
|
||||
- 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 { #v3.0.0 }
|
||||
|
||||
### :octicons-alert-24:{ .changelog-breaking title="Breaking Changes" } Breaking Changes { #v3-breaking }
|
||||
|
||||
@@ -45,7 +54,7 @@ They are ordered newest to oldest.
|
||||
|
||||
----
|
||||
|
||||
## v2.1.0
|
||||
## v2.1.0 { #v2.1.0 }
|
||||
|
||||
### :octicons-pencil-24:{ .changelog-changed title="Changed" } Changed { #v2.1.0-changed }
|
||||
|
||||
@@ -54,7 +63,7 @@ They are ordered newest to oldest.
|
||||
|
||||
----
|
||||
|
||||
## v2.0.0
|
||||
## v2.0.0 { #v2.0.0 }
|
||||
|
||||
### :octicons-alert-24:{ .changelog-breaking title="Breaking Changes" } Breaking Changes { #v2-breaking }
|
||||
|
||||
@@ -85,7 +94,7 @@ They are ordered newest to oldest.
|
||||
|
||||
----
|
||||
|
||||
## v1.0.0
|
||||
## v1.0.0 { #v1.0.0 }
|
||||
|
||||
### :octicons-plus-circle-24:{ .changelog-added title="Added" } Added { #v1-added }
|
||||
|
||||
|
||||
+327
-94
@@ -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
|
||||
@@ -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 -->
|
||||
@@ -27,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>
|
||||
@@ -43,12 +43,12 @@ Below is a list of all custom tags. Note that these tags only render on the actu
|
||||
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:
|
||||
|
||||
@@ -88,7 +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 explanation.
|
||||
- `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.
|
||||
@@ -128,10 +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 explanation.
|
||||
- `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.
|
||||
@@ -166,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.
|
||||
@@ -179,7 +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 explanation.
|
||||
- `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.
|
||||
|
||||
@@ -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 -->
|
||||
@@ -2,7 +2,7 @@ document$.subscribe(async () => {
|
||||
const url = 'https://codeberg-stats-proxy.vercel.app/repo'
|
||||
const repo_stats = document.querySelector('[data-md-component="source"] .md-source__repository');
|
||||
|
||||
function loadInfo(data) {
|
||||
function loadCodebergInfo(data) {
|
||||
const facts = document.createElement("ul");
|
||||
facts.className = "md-source__facts";
|
||||
|
||||
@@ -26,6 +26,35 @@ document$.subscribe(async () => {
|
||||
repo_stats.appendChild(facts);
|
||||
}
|
||||
|
||||
function loadApiInfo(data) {
|
||||
const version = data["version"];
|
||||
const versionToken = '{apiVersion}';
|
||||
const codeBlocks = document.querySelectorAll('.md-content pre code');
|
||||
for(const codeBlock of codeBlocks) {
|
||||
codeBlock.innerHTML = codeBlock.innerHTML.replace(new RegExp(versionToken, 'g'), version);
|
||||
}
|
||||
}
|
||||
|
||||
function loadPluginVersion(data) {
|
||||
const version = data["version"];
|
||||
const versionToken = '{version}'
|
||||
const entries = document.querySelectorAll('.md-content code');
|
||||
for(const entry of entries) {
|
||||
entry.innerHTML = entry.innerHTML.replace(new RegExp(versionToken, 'g'), version.substring(1));
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchApiInfo() {
|
||||
const tag = await fetch("https://api.github.com/repos/Andre601/asl-api/releases/latest").then(_ => _.json());
|
||||
|
||||
const data = {
|
||||
"version": tag.tag_name
|
||||
};
|
||||
|
||||
__md_set("__api_tag", data, sessionStorage);
|
||||
loadApiInfo(data);
|
||||
}
|
||||
|
||||
async function fetchInfo() {
|
||||
const [release, repo] = await Promise.all([
|
||||
fetch(`${url}/latest-release`).then(_ => _.json()),
|
||||
@@ -39,15 +68,26 @@ document$.subscribe(async () => {
|
||||
};
|
||||
|
||||
__md_set("__git_repo", data, sessionStorage);
|
||||
loadInfo(data);
|
||||
loadCodebergInfo(data);
|
||||
loadPluginVersion(data);
|
||||
}
|
||||
|
||||
if(!document.querySelector('[data-md-component="source"] .md-source__facts')){
|
||||
if(!document.querySelector('[data-md-component="source"] .md-source__facts')) {
|
||||
const cached = __md_get("__git_repo", sessionStorage);
|
||||
if((cached != null) && (cached["version"])) {
|
||||
loadInfo(cached);
|
||||
loadCodebergInfo(cached);
|
||||
loadPluginVersion(cached);
|
||||
} else {
|
||||
fetchInfo();
|
||||
}
|
||||
}
|
||||
|
||||
if(location.href.includes('/api/')) {
|
||||
const cachedApi = __md_get("__api_tag", sessionStorage);
|
||||
if((cachedApi != null) && (cachedApi["version"])) {
|
||||
loadApiInfo(cachedApi);
|
||||
} else {
|
||||
fetchApiInfo();
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,279 @@
|
||||
:root {
|
||||
--md-badge-fg--note: #448aff;
|
||||
--md-badge-bg--note: #448aff1a;
|
||||
--md-badge-fg--abstract: #00b0ff;
|
||||
--md-badge-bg--abstract: #00b0ff1a;
|
||||
--md-badge-fg--info: #00b8d4;
|
||||
--md-badge-bg--info: #00b8d41a;
|
||||
--md-badge-fg--tip: #00bfa5;
|
||||
--md-badge-bg--tip: #00bfa51a;
|
||||
--md-badge-fg--success: #00c853;
|
||||
--md-badge-bg--success: #00c8531a;
|
||||
--md-badge-fg--question: #64dd17;
|
||||
--md-badge-bg--question: #64dd171a;
|
||||
--md-badge-fg--warning: #ff9100;
|
||||
--md-badge-bg--warning: #ff91001a;
|
||||
--md-badge-fg--failure: #ff5252;
|
||||
--md-badge-bg--failure: #ff52521a;
|
||||
--md-badge-fg--danger: #ff1744;
|
||||
--md-badge-bg--danger: #ff17441a;
|
||||
--md-badge-fg--bug: #f50057;
|
||||
--md-badge-bg--bug: #f500571a;
|
||||
--md-badge-fg--example: #7c4dff;
|
||||
--md-badge-bg--example: #7c4dff1a;
|
||||
--md-badge-fg--quote: #9e9e9e;
|
||||
--md-badge-bg--quote: #9e9e9e1a;
|
||||
--md-badge-fg--deprecated: #ff5252;
|
||||
--md-badge-bg--deprecated: #ff52521a;
|
||||
|
||||
--badge-icon--note: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M17.263 2.177a1.75 1.75 0 0 1 2.474 0l2.586 2.586a1.75 1.75 0 0 1 0 2.474L19.53 10.03l-.012.013L8.69 20.378a1.753 1.753 0 0 1-.699.409l-5.523 1.68a.748.748 0 0 1-.747-.188.748.748 0 0 1-.188-.747l1.673-5.5a1.75 1.75 0 0 1 .466-.756L14.476 4.963ZM4.708 16.361a.26.26 0 0 0-.067.108l-1.264 4.154 4.177-1.271a.253.253 0 0 0 .1-.059l10.273-9.806-2.94-2.939-10.279 9.813ZM19 8.44l2.263-2.262a.25.25 0 0 0 0-.354l-2.586-2.586a.25.25 0 0 0-.354 0L16.061 5.5Z"></path></svg>');
|
||||
--badge-icon--abstract: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M5.962 2.513a.75.75 0 0 1-.475.949l-.816.272a.25.25 0 0 0-.171.237V21.25c0 .138.112.25.25.25h14.5a.25.25 0 0 0 .25-.25V3.97a.25.25 0 0 0-.17-.236l-.817-.272a.75.75 0 0 1 .474-1.424l.816.273A1.751 1.751 0 0 1 21 3.97v17.28A1.75 1.75 0 0 1 19.25 23H4.75A1.75 1.75 0 0 1 3 21.25V3.97a1.75 1.75 0 0 1 1.197-1.66l.816-.272a.75.75 0 0 1 .949.475Z"></path><path d="M7 1.75C7 .784 7.784 0 8.75 0h6.5C16.216 0 17 .784 17 1.75v1.5A1.75 1.75 0 0 1 15.25 5h-6.5A1.75 1.75 0 0 1 7 3.25Zm1.75-.25a.25.25 0 0 0-.25.25v1.5c0 .138.112.25.25.25h6.5a.25.25 0 0 0 .25-.25v-1.5a.25.25 0 0 0-.25-.25Z"></path></svg>');
|
||||
--badge-icon--info: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M13 7.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm-3 3.75a.75.75 0 0 1 .75-.75h1.5a.75.75 0 0 1 .75.75v4.25h.75a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1 0-1.5h.75V12h-.75a.75.75 0 0 1-.75-.75Z"></path><path d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Z"></path></svg>');
|
||||
--badge-icon--tip: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 2.5c-3.81 0-6.5 2.743-6.5 6.119 0 1.536.632 2.572 1.425 3.56.172.215.347.422.527.635l.096.112c.21.25.427.508.63.774.404.531.783 1.128.995 1.834a.75.75 0 0 1-1.436.432c-.138-.46-.397-.89-.753-1.357a18.111 18.111 0 0 0-.582-.714l-.092-.11c-.18-.212-.37-.436-.555-.667C4.87 12.016 4 10.651 4 8.618 4 4.363 7.415 1 12 1s8 3.362 8 7.619c0 2.032-.87 3.397-1.755 4.5-.185.23-.375.454-.555.667l-.092.109c-.21.248-.405.481-.582.714-.356.467-.615.898-.753 1.357a.751.751 0 0 1-1.437-.432c.213-.706.592-1.303.997-1.834.202-.266.419-.524.63-.774l.095-.112c.18-.213.355-.42.527-.634.793-.99 1.425-2.025 1.425-3.561C18.5 5.243 15.81 2.5 12 2.5ZM8.75 18h6.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5Zm.75 3.75a.75.75 0 0 1 .75-.75h3.5a.75.75 0 0 1 0 1.5h-3.5a.75.75 0 0 1-.75-.75Z"></path></svg>');
|
||||
--badge-icon--success: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M21.03 5.72a.75.75 0 0 1 0 1.06l-11.5 11.5a.747.747 0 0 1-1.072-.012l-5.5-5.75a.75.75 0 1 1 1.084-1.036l4.97 5.195L19.97 5.72a.75.75 0 0 1 1.06 0Z"></path></svg>');
|
||||
--badge-icon--question: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M10.97 8.265a1.45 1.45 0 0 0-.487.57.75.75 0 0 1-1.341-.67c.2-.402.513-.826.997-1.148C10.627 6.69 11.244 6.5 12 6.5c.658 0 1.369.195 1.934.619a2.45 2.45 0 0 1 1.004 2.006c0 1.033-.513 1.72-1.027 2.215-.19.183-.399.358-.579.508l-.147.123a4.329 4.329 0 0 0-.435.409v1.37a.75.75 0 1 1-1.5 0v-1.473c0-.237.067-.504.247-.736.22-.28.486-.517.718-.714l.183-.153.001-.001c.172-.143.324-.27.47-.412.368-.355.569-.676.569-1.136a.953.953 0 0 0-.404-.806C12.766 8.118 12.384 8 12 8c-.494 0-.814.121-1.03.265ZM13 17a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path><path d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Z"></path></svg>');
|
||||
--badge-icon--warning: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M13 17.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm-.25-8.25a.75.75 0 0 0-1.5 0v4.5a.75.75 0 0 0 1.5 0v-4.5Z"></path><path d="M9.836 3.244c.963-1.665 3.365-1.665 4.328 0l8.967 15.504c.963 1.667-.24 3.752-2.165 3.752H3.034c-1.926 0-3.128-2.085-2.165-3.752Zm3.03.751a1.002 1.002 0 0 0-1.732 0L2.168 19.499A1.002 1.002 0 0 0 3.034 21h17.932a1.002 1.002 0 0 0 .866-1.5L12.866 3.994Z"></path></svg>');
|
||||
--badge-icon--failure: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M5.72 5.72a.75.75 0 0 1 1.06 0L12 10.94l5.22-5.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L13.06 12l5.22 5.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L12 13.06l-5.22 5.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L10.94 12 5.72 6.78a.75.75 0 0 1 0-1.06Z"></path></svg>');
|
||||
--badge-icon--danger: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M15.716 1.329a1.341 1.341 0 0 1 2.109 1.55L15.147 9h4.161c1.623 0 2.372 2.016 1.143 3.075L8.102 22.721a1.148 1.148 0 0 1-1.81-1.317L8.996 15H4.674c-1.619 0-2.37-2.008-1.148-3.07l12.19-10.6Zm.452 1.595L4.51 13.061a.25.25 0 0 0 .164.439h5.45a.749.749 0 0 1 .692 1.041l-2.559 6.066 11.215-9.668a.25.25 0 0 0-.164-.439H14a.75.75 0 0 1-.687-1.05Z"></path></svg>');
|
||||
--badge-icon--bug: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M7.72.22a.75.75 0 0 1 1.06 0l1.204 1.203A4.98 4.98 0 0 1 12 1c.717 0 1.4.151 2.016.423L15.22.22a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-.971.972A4.991 4.991 0 0 1 17 6v1.104a2.755 2.755 0 0 1 1.917 1.974l1.998-.999a.75.75 0 0 1 .67 1.342L19 10.714V13.5l3.25.003a.75.75 0 0 1 0 1.5L19 15.001V16c0 .568-.068 1.134-.204 1.686l.04.018 2.75 1.375a.75.75 0 1 1-.671 1.342l-2.638-1.319A6.998 6.998 0 0 1 12 23a6.998 6.998 0 0 1-6.197-3.742l-2.758 1.181a.752.752 0 0 1-1.064-.776.752.752 0 0 1 .474-.602l2.795-1.199A6.976 6.976 0 0 1 5 16v-.996H1.75a.75.75 0 0 1 0-1.5H5v-2.79L2.415 9.42a.75.75 0 0 1 .67-1.342l1.998.999A2.756 2.756 0 0 1 7 7.104V6a4.99 4.99 0 0 1 1.69-3.748l-.97-.972a.75.75 0 0 1 0-1.06ZM6.5 9.75V16a5.5 5.5 0 1 0 11 0V9.75c0-.69-.56-1.25-1.25-1.25h-8.5c-.69 0-1.25.56-1.25 1.25ZM8.5 7h7V6a3.5 3.5 0 1 0-7 0Z"></path></svg>');
|
||||
--badge-icon--example: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M8 8.807V3.5h-.563a.75.75 0 0 1 0-1.5h9.125a.75.75 0 0 1 0 1.5H16v5.307l5.125 9.301c.964 1.75-.302 3.892-2.299 3.892H5.174c-1.998 0-3.263-2.142-2.3-3.892ZM4.189 18.832a1.123 1.123 0 0 0 .985 1.668h13.652a1.123 1.123 0 0 0 .985-1.668L17.7 15H6.3ZM14.5 3.5h-5V9a.75.75 0 0 1-.093.362L7.127 13.5h9.746l-2.28-4.138A.75.75 0 0 1 14.5 9Z"></path></svg>');
|
||||
--badge-icon--quote: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M3 6.25a.75.75 0 0 1 .75-.75h13.5a.75.75 0 0 1 0 1.5H3.75A.75.75 0 0 1 3 6.25Zm5 6.063a.75.75 0 0 1 .75-.75h11.5a.75.75 0 0 1 0 1.5H8.75a.75.75 0 0 1-.75-.75Zm0 5.937a.75.75 0 0 1 .75-.75h11.5a.75.75 0 0 1 0 1.5H8.75a.75.75 0 0 1-.75-.75ZM3.75 11a.75.75 0 0 1 .75.75v7a.75.75 0 0 1-1.5 0v-7a.75.75 0 0 1 .75-.75Z"></path></svg>');
|
||||
--badge-icon--deprecated: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M16 1.75V3h5.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H8V1.75C8 .784 8.784 0 9.75 0h4.5C15.216 0 16 .784 16 1.75Zm-6.5 0V3h5V1.75a.25.25 0 0 0-.25-.25h-4.5a.25.25 0 0 0-.25.25ZM4.997 6.178a.75.75 0 1 0-1.493.144L4.916 20.92a1.75 1.75 0 0 0 1.742 1.58h10.684a1.75 1.75 0 0 0 1.742-1.581l1.413-14.597a.75.75 0 0 0-1.494-.144l-1.412 14.596a.25.25 0 0 1-.249.226H6.658a.25.25 0 0 1-.249-.226L4.997 6.178Z"></path><path d="M9.206 7.501a.75.75 0 0 1 .793.705l.5 8.5A.75.75 0 1 1 9 16.794l-.5-8.5a.75.75 0 0 1 .705-.793Zm6.293.793A.75.75 0 1 0 14 8.206l-.5 8.5a.75.75 0 0 0 1.498.088l.5-8.5Z"></path></svg>');
|
||||
}
|
||||
|
||||
/*
|
||||
* Grid stuff
|
||||
*/
|
||||
.mdx-grid-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: .5fr 9fr;
|
||||
gap: 1rem;
|
||||
|
||||
border: .075rem solid var(--md-badge-fg--note);
|
||||
border-radius: .2rem;
|
||||
}
|
||||
|
||||
.mdx-grid-child {
|
||||
align-self: center;
|
||||
font-size: .64rem;
|
||||
}
|
||||
|
||||
.mdx-grid-child.mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--note);
|
||||
}
|
||||
|
||||
.mdx-grid-child.mdx-grid-child--icon::before {
|
||||
content: "";
|
||||
|
||||
background-color: var(--md-badge-fg--note);
|
||||
|
||||
mask-position: center;
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
|
||||
margin: .4rem;
|
||||
|
||||
display: block;
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--note);
|
||||
mask-image: var(--badge-icon--note);
|
||||
}
|
||||
|
||||
/*
|
||||
* Types
|
||||
*/
|
||||
|
||||
/* Abstract */
|
||||
.mdx-admo--abstract {
|
||||
border-color: var(--md-badge-fg--abstract);
|
||||
}
|
||||
|
||||
.mdx-admo--abstract .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--abstract);
|
||||
}
|
||||
|
||||
.mdx-admo--abstract .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--abstract);
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--abstract);
|
||||
mask-image: var(--badge-icon--abstract);
|
||||
}
|
||||
|
||||
/* Info */
|
||||
.mdx-admo--info {
|
||||
border-color: var(--md-badge-fg--info);
|
||||
}
|
||||
|
||||
.mdx-admo--info .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--info);
|
||||
}
|
||||
|
||||
.mdx-admo--info .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--info);
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--info);
|
||||
mask-image: var(--badge-icon--info);
|
||||
}
|
||||
|
||||
/* Tip */
|
||||
.mdx-admo--tip {
|
||||
border-color: var(--md-badge-fg--tip);
|
||||
}
|
||||
|
||||
.mdx-admo--tip .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--tip);
|
||||
}
|
||||
|
||||
.mdx-admo--tip .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--tip);
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--tip);
|
||||
mask-image: var(--badge-icon--tip);
|
||||
}
|
||||
|
||||
/* Success */
|
||||
.mdx-admo--success {
|
||||
border-color: var(--md-badge-fg--success);
|
||||
}
|
||||
|
||||
.mdx-admo--success .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--success);
|
||||
}
|
||||
|
||||
.mdx-admo--success .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--success);
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--success);
|
||||
mask-image: var(--badge-icon--success);
|
||||
}
|
||||
|
||||
/* Question */
|
||||
.mdx-admo--question {
|
||||
border-color: var(--md-badge-fg--question);
|
||||
}
|
||||
|
||||
.mdx-admo--question .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--question);
|
||||
}
|
||||
|
||||
.mdx-admo--question .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--question);
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--question);
|
||||
mask-image: var(--badge-icon--question);
|
||||
}
|
||||
|
||||
/* Warning */
|
||||
.mdx-admo--warning {
|
||||
border-color: var(--md-badge-fg--warning);
|
||||
}
|
||||
|
||||
.mdx-admo--warning .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--warning);
|
||||
}
|
||||
|
||||
.mdx-admo--warning .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--warning);
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--warning);
|
||||
mask-image: var(--badge-icon--warning);
|
||||
}
|
||||
|
||||
/* Failure */
|
||||
.mdx-admo--failure {
|
||||
border-color: var(--md-badge-fg--failure);
|
||||
}
|
||||
|
||||
.mdx-admo--failure .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--failure);
|
||||
}
|
||||
|
||||
.mdx-admo--failure .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--failure);
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--failure);
|
||||
mask-image: var(--badge-icon--failure);
|
||||
}
|
||||
|
||||
/* Danger */
|
||||
.mdx-admo--danger {
|
||||
border-color: var(--md-badge-fg--danger);
|
||||
}
|
||||
|
||||
.mdx-admo--danger .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--danger);
|
||||
}
|
||||
|
||||
.mdx-admo--danger .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--danger);
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--danger);
|
||||
mask-image: var(--badge-icon--danger);
|
||||
}
|
||||
|
||||
/* Bug */
|
||||
.mdx-admo--bug {
|
||||
border-color: var(--md-badge-fg--bug);
|
||||
}
|
||||
|
||||
.mdx-admo--bug .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--bug);
|
||||
}
|
||||
|
||||
.mdx-admo--bug .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--bug);
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--bug);
|
||||
mask-image: var(--badge-icon--bug);
|
||||
}
|
||||
|
||||
/* Example */
|
||||
.mdx-admo--example {
|
||||
border-color: var(--md-badge-fg--example);
|
||||
}
|
||||
|
||||
.mdx-admo--example .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--example);
|
||||
}
|
||||
|
||||
.mdx-admo--example .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--example);
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--example);
|
||||
mask-image: var(--badge-icon--example);
|
||||
}
|
||||
|
||||
/* Quote */
|
||||
.mdx-admo--quote {
|
||||
border-color: var(--md-badge-fg--quote);
|
||||
}
|
||||
|
||||
.mdx-admo--quote .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--quote);
|
||||
}
|
||||
|
||||
.mdx-admo--quote .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--quote);
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--quote);
|
||||
mask-image: var(--badge-icon--quote);
|
||||
}
|
||||
|
||||
/* Deprecated */
|
||||
.mdx-admo--deprecated {
|
||||
border-color: var(--md-badge-fg--deprecated);
|
||||
}
|
||||
|
||||
.mdx-admo--deprecated .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--deprecated);
|
||||
}
|
||||
|
||||
.mdx-admo--deprecated .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--deprecated);
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--deprecated);
|
||||
mask-image: var(--badge-icon--deprecated);
|
||||
}
|
||||
@@ -20,6 +20,8 @@
|
||||
--color-api-bg__static: #00c8531a;
|
||||
--color-api-bg__final: #ff91001a;
|
||||
--color-api-bg__abstract: #00bfa51a;
|
||||
|
||||
--md-admonition-icon--deprecated: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M16 1.75V3h5.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H8V1.75C8 .784 8.784 0 9.75 0h4.5C15.216 0 16 .784 16 1.75Zm-6.5 0V3h5V1.75a.25.25 0 0 0-.25-.25h-4.5a.25.25 0 0 0-.25.25ZM4.997 6.178a.75.75 0 1 0-1.493.144L4.916 20.92a1.75 1.75 0 0 0 1.742 1.58h10.684a1.75 1.75 0 0 0 1.742-1.581l1.413-14.597a.75.75 0 0 0-1.494-.144l-1.412 14.596a.25.25 0 0 1-.249.226H6.658a.25.25 0 0 1-.249-.226L4.997 6.178Z"></path><path d="M9.206 7.501a.75.75 0 0 1 .793.705l.5 8.5A.75.75 0 1 1 9 16.794l-.5-8.5a.75.75 0 0 1 .705-.793Zm6.293.793A.75.75 0 1 0 14 8.206l-.5 8.5a.75.75 0 0 0 1.498.088l.5-8.5Z"></path></svg>');
|
||||
}
|
||||
|
||||
/* Page design */
|
||||
@@ -148,4 +150,21 @@ api__record::before {
|
||||
.api-type__primitive {
|
||||
color: var(--color-api-fg-type__primitive);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.md-typeset .admonition.deprecated,
|
||||
.md-typeset details.deprecated {
|
||||
border-color: var(--color-api-fg__deprecated);
|
||||
}
|
||||
|
||||
.md-typeset .deprecated > .admonition-title,
|
||||
.md-typeset .deprecated > summary {
|
||||
background-color: var(--color-api-bg__deprecated);
|
||||
}
|
||||
|
||||
.md-typeset .deprecated > .admonition-title::before,
|
||||
.md-typeset .deprecated > summary::before {
|
||||
background-color: var(--color-api-fg__deprecated);
|
||||
-webkit-mask-image: var(--md-admonition-icon--deprecated);
|
||||
mask-image: var(--md-admonition-icon--deprecated);
|
||||
}
|
||||
+32
-16
@@ -6,7 +6,7 @@ icon: octicons/list-unordered-24
|
||||
|
||||
## About
|
||||
|
||||
!!! warning "The below examples may only work in v1.10.0 or newer!"
|
||||
<!-- admo:info The below examples may only work in v3.7.0 or newer! -->
|
||||
|
||||
This page lists some examples you may want to use for your proxy or server.
|
||||
|
||||
@@ -17,7 +17,9 @@ Feel free to suggest additional examples on my [Discord Server](https://discord.
|
||||
- [Versions](#versions)
|
||||
- [Different List for outdated Clients](#different-list-for-outdated-clients)
|
||||
- [Different MOTD for < 1.16](#different-motd-for-116)
|
||||
- [Spigot/PaperMC](#spigotpapermc)
|
||||
- [BungeeCord/Velocity](#bungeecordvelocity)
|
||||
- [Display MOTD for a set of subdomains](#display-motd-for-a-set-of-subdomains)
|
||||
- [PaperMC](#papermc)
|
||||
- [Different profile for banned Player](#different-profile-for-banned-player)
|
||||
- [Other](#other)
|
||||
- [Different profile for different host](#different-profile-for-different-host)
|
||||
@@ -38,8 +40,7 @@ This example here shows a separate MOTD and player count message for when the pl
|
||||
priority: 1
|
||||
|
||||
# Display this profile, if the version of the player is below 760 (1.19.1)
|
||||
conditions:
|
||||
- '${player protocol} < 760'
|
||||
condition: '${player protocol} < 760'
|
||||
|
||||
motd:
|
||||
- '<red>You are using an outdated client!'
|
||||
@@ -57,8 +58,7 @@ This profile would display a MOTD without HEX colours if the player's version is
|
||||
priority: 1
|
||||
|
||||
# Display this profile, if the version of the player is below 735 (1.16)
|
||||
conditions:
|
||||
- '${player protocol} < 735'
|
||||
condition: '${player protocol} < 735'
|
||||
|
||||
motd:
|
||||
- '<grey>Welcome to <aqua>YourServer.com</aqua>!'
|
||||
@@ -66,21 +66,39 @@ motd:
|
||||
```
|
||||
|
||||
----
|
||||
## Spigot/PaperMC
|
||||
## BungeeCord/Velocity
|
||||
|
||||
Examples that can be used with the Spigot or PaperMC version.
|
||||
Examples usable on the BungeeCord and Velocity version.
|
||||
|
||||
### Display MOTD for a set of subdomains
|
||||
|
||||
Displays the same MOTDs for the server when pinged on any sub-domain starting with `lobby` (i.e. `lobby-1.example.com`).
|
||||
|
||||
```yaml title="lobby-motd.yml"
|
||||
priority: 1
|
||||
|
||||
condition: '${server host} |- "lobby"'
|
||||
|
||||
motd:
|
||||
- '<green>Lobby Server'
|
||||
- '<grey>Example Server'
|
||||
```
|
||||
|
||||
----
|
||||
## PaperMC
|
||||
|
||||
Examples that can be used with the PaperMC version.
|
||||
|
||||
### Different profile for banned Player
|
||||
|
||||
!!! warning "Requires a cached player to work reliably."
|
||||
<!-- admo:info Requires a cached player -->
|
||||
|
||||
Displays a separate profile for when the player has been banned from the server.
|
||||
|
||||
```yaml title="banned.yml"
|
||||
priority: 1
|
||||
|
||||
conditions:
|
||||
- '${player isBanned} = true'
|
||||
condition: '${player isBanned}'
|
||||
|
||||
motd:
|
||||
- '<red>You have been <bold>BANNED</bold>!'
|
||||
@@ -103,8 +121,7 @@ Display a different profile when the playing pings a specific domain/IP.
|
||||
```yaml title="specific-host.yml"
|
||||
priority: 1
|
||||
|
||||
conditions:
|
||||
- '${server host} = other.example.com'
|
||||
condition: '${server host} = "host.example.com"'
|
||||
|
||||
motd:
|
||||
- '<grey>Please use <aqua>mc.example.com'
|
||||
@@ -118,12 +135,11 @@ Display a different profile, if the player pinging the server is "known" by Adva
|
||||
```yaml title="personalized.yml"
|
||||
priority: 1
|
||||
|
||||
conditions:
|
||||
- `${player name} != Anonymous` # "Anonymous" should be replaced with whatever you use in 'unknown_player'
|
||||
condition: '${player name} != "Anonymous"' # "Anonymous" would be the value from the "unknownPlayer > name" option.
|
||||
|
||||
motd:
|
||||
- '<grey>Hello there <aqua>${player name}</aqua>!'
|
||||
- '<grey>It's nice to see you again.'
|
||||
- '<grey>It''s nice to see you again.'
|
||||
|
||||
playerCount:
|
||||
hover:
|
||||
|
||||
@@ -0,0 +1,431 @@
|
||||
---
|
||||
icon: octicons/milestone-24
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
|
||||
This page will explain how to set up AdvancedServerList and make it work for your server.
|
||||
It tries to be an easy to understand as possible. But if you still have problems, consider joining the [Discord Server](https://discord.gg/6dazXp6) for help.
|
||||
|
||||
## 1. Download the plugin { #download-the-plugin }
|
||||
|
||||
The first step would be to download the plugin from a download page of your choice. As of writing this is AdvancedServerList updated and available on these sites:
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- [:simple-modrinth: **Modrinth**][modrinth]
|
||||
|
||||
----
|
||||
|
||||
:octicons-check-24:{ style="color: var(--md-badge-fg--success);" } **Actively updated!**
|
||||
|
||||
- [:simple-codeberg: **Codeberg**][codeberg]
|
||||
|
||||
----
|
||||
|
||||
:octicons-check-24:{ style="color: var(--md-badge-fg--success);" } **Actively updated!**
|
||||
|
||||
- [:fontawesome-solid-paper-plane: **HangarMC**][hangar]
|
||||
|
||||
----
|
||||
|
||||
:octicons-alert-24:{ style="color: var(--md-badge-fg--warning);" } **On Pause!**
|
||||
|
||||
- [:simple-spigotmc: **SpigotMC**][spigot]
|
||||
|
||||
----
|
||||
|
||||
:octicons-alert-24:{ style="color: var(--md-badge-fg--warning);" } **Discontinued!**
|
||||
|
||||
</div>
|
||||
|
||||
[modrinth]: https://modrinth.com/plugin/advancedserverlist
|
||||
[codeberg]: https://codeberg.org/Andre601/AdvancedServerList
|
||||
[spigot]: https://www.spigotmc.org/resources/102910/
|
||||
[hangar]: https://hangar.papermc.io/Andre_601/AdvancedServerList
|
||||
|
||||
The plugin is available for Paper, BungeeCord, Waterfall and Velocity, and has been tested on these platforms. It may support additional forks, but this is not guaranteed.
|
||||
|
||||
The plugin also supports these additional plugins. They are all optional.
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- [**PlaceholderAPI**][placeholderapi]
|
||||
|
||||
----
|
||||
|
||||
Supported on:
|
||||
|
||||
- :fontawesome-solid-paper-plane: Paper
|
||||
|
||||
- [**ViaVersion**][viaversion]
|
||||
|
||||
----
|
||||
|
||||
Supported on:
|
||||
|
||||
- :fontawesome-solid-paper-plane: Paper
|
||||
|
||||
- [**PAPIProxyBridge**][papiproxybridge]
|
||||
|
||||
----
|
||||
|
||||
Supported on:
|
||||
|
||||
- :simple-spigotmc: BungeeCord
|
||||
- :fontawesome-solid-paper-plane: Velocity
|
||||
|
||||
- [**Maintenance**][maintenance]
|
||||
|
||||
----
|
||||
|
||||
Supported on:
|
||||
|
||||
- :fontawesome-solid-paper-plane: Paper
|
||||
- :simple-spigotmc: BungeeCord
|
||||
- :fontawesome-solid-paper-plane: Velocity
|
||||
|
||||
</div>
|
||||
|
||||
[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
|
||||
|
||||
## 2. Installation { #installation }
|
||||
|
||||
Installing the plugin is as simple as moving the jar file into the plugins folder. Just make sure to download the right version of AdvancedServerList for the right platform.
|
||||
Here is a quick table showing the jar file name with the platforms it is made for:
|
||||
|
||||
| Jar file name | Platforms |
|
||||
|-----------------------------------------------|-----------------------|
|
||||
| `AdvancedServerList-Paper-{version}.jar` | Paper |
|
||||
| `AdvancedServerList-BungeeCord-{version}.jar` | BungeeCord, Waterfall |
|
||||
| `AdvancedServerList-Velocity-{version}.jar` | Velocity |
|
||||
|
||||
After you added it to your plugins folder - alongside any other dependency you may want - (re)start your server or proxy to enable the plugin.
|
||||
If everything goes well should AdvancedServerList create a folder named `AdvancedServerList` (`advancedserverlist` on Velocity) with additional files and folders inside of it.
|
||||
|
||||
### Folder structure
|
||||
|
||||
When you install AdvancedServerList for the first time should it have created the following file structure inside the plugins folder of your Server or Proxy:
|
||||
```
|
||||
AdvancedServerList/
|
||||
├── favicons/
|
||||
├── profiles/
|
||||
│ └── default.yml
|
||||
└── config.yml
|
||||
```
|
||||
Let's cover the files and folders...
|
||||
|
||||
#### Favicons folder
|
||||
|
||||
This folder allows you to store PNG images that should be used as favicons by the plugin. A favicon from this folder can be used by referencing the name (Including the `.png` file extension) in the [`favicon` option of the server list profile](../profiles/index.md#favicon).
|
||||
|
||||
#### Profiles folder and default.yml { #profiles-folder-and-default-yml }
|
||||
|
||||
The profiles folder is home of the server list profile files which allow you to modify the server list entry of your server in a player's multiplayer screen.
|
||||
On first creation will the folder have a `default.yml` file. This file contains all the options available to use alongside comments to try and help you in using it properly.
|
||||
|
||||
/// details | default.yml content
|
||||
```yaml
|
||||
#
|
||||
# Set the priority of this profile.
|
||||
# Higher number = Higher 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'
|
||||
|
||||
#
|
||||
# Option that allows you to define multiple profiles to use.
|
||||
# Each entry supports the same options as the server list profile does. Whenever an option is not present, or set to
|
||||
# an empty value (If supported) would the option in the file be used (if present).
|
||||
# This allows you to f.e. randomize the MOTD while keeping other options the same, without copy-pasting the same options.
|
||||
#
|
||||
# A profile will be selected randomly.
|
||||
#
|
||||
# Remove this option or set it to profiles: [] to use the global options of this file.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#profiles
|
||||
#
|
||||
#profiles:
|
||||
# - motd:
|
||||
# - '<aqua>Line 1'
|
||||
# - '<aqua>Line 2'
|
||||
# favicon: ''
|
||||
# playerCount:
|
||||
# hidePlayers: false
|
||||
# hover:
|
||||
# - '<green>Line 1'
|
||||
# - '<green>Line 2'
|
||||
# - '<green>Line 3'
|
||||
# text: ''
|
||||
# extraPlayers:
|
||||
# enabled: false
|
||||
# amount: 0
|
||||
|
||||
#
|
||||
# Set the default (Global) MOTD used by this server list profile.
|
||||
# Supports HEX colors for 1.16+ servers including gradients using MiniMessage's <gradient:color:color> format.
|
||||
#
|
||||
# Remove this option or set it to motd: [] to not alter the MOTD.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#motd
|
||||
#
|
||||
motd:
|
||||
- '<grey>Line 1'
|
||||
- '<grey>Line 2'
|
||||
|
||||
#
|
||||
# Allows you to set a global (Default) favicon for this server list profile.
|
||||
# You can use one of three possible options:
|
||||
# 1. A file name matching a PNG file located in the 'favicons' folder (Needs to end with .png)
|
||||
# 2. A URL pointing to a valid Image
|
||||
# 3. ${player name} to display the player's head as favicon. Uses https://mc-heads.net for this
|
||||
#
|
||||
# Remove this option or set to favicon: '' to not replace the Favicon.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#favicon
|
||||
#
|
||||
favicon: ''
|
||||
|
||||
#
|
||||
# Contains various options to manipulate the player count (Text displaying online and max players allowed).
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#playercount
|
||||
#
|
||||
playerCount:
|
||||
#
|
||||
# Whether AdvancedServerList should hide the player count or not.
|
||||
# When set to true will the player count display '???' instead of <online>/<max>
|
||||
#
|
||||
# Note that when this is enabled will all other options, except for 'extraPlayers', be ignored.
|
||||
#
|
||||
# Defaults to false when not present.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#hideplayers
|
||||
#
|
||||
hidePlayers: false
|
||||
#
|
||||
# Sets the text displayed when hovering over the player count.
|
||||
#
|
||||
# Remove this option or set it to hover: [] to not modify the player samples on the player count.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#hover
|
||||
#
|
||||
hover:
|
||||
- '<grey>Line 1'
|
||||
- '<grey>Line 2'
|
||||
- '<grey>Line 3'
|
||||
#
|
||||
# Modifies the text that usually displays '<online>/<max>'
|
||||
#
|
||||
# Note that when used, the Ping icon will display as 'outdated server'/'outdated client'.
|
||||
# This is nothing that can be fixed or avoided and would require changes from Mojang.
|
||||
#
|
||||
# Remove this option or set it to text: '' to not modify the player count 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://asl.andre601.ch/profiles/#extraplayers
|
||||
#
|
||||
extraPlayers:
|
||||
#
|
||||
# Enables/Disables the extraPlayers option.
|
||||
# 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://asl.andre601.ch/profiles/#extraplayers-enabled
|
||||
#
|
||||
enabled: false
|
||||
#
|
||||
# Sets how much should be added/subtracted from the current number of online players
|
||||
# to then use for the max player count.
|
||||
#
|
||||
# Example:
|
||||
# When set to 1 while 10 players are online would the player count - if unmodified -
|
||||
# display '10/11'. When -1 is used will it display '10/9'
|
||||
#
|
||||
# Defaults to 0 when not present.
|
||||
#
|
||||
# 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
|
||||
```
|
||||
///
|
||||
|
||||
#### Config.yml
|
||||
|
||||
The config.yml file contains settings related to the plugin itself and some of its functionality.
|
||||
These functions include, but aren't limited to:
|
||||
|
||||
- Setting the default name and UUID used for an unknown (Not cached) player.
|
||||
- Disabling/Enabling caching of players.
|
||||
- Disabling/Enabling checking for updates.
|
||||
- Disabling/Enabling debug mode.
|
||||
- The config version used for migration. Don't touch this, or it may reset your config.
|
||||
|
||||
Similar to the default.yml is this file containing comments to try and explain the settings in questions.
|
||||
Do note that if the config gets migrated from an older version, that the comments will be discarded in the process, unfortunately.
|
||||
|
||||
/// details | default config.yml content
|
||||
```yaml
|
||||
#
|
||||
# Used for when AdvancedServerList doesn't have a cached player to use for player placeholders.
|
||||
#
|
||||
unknownPlayer:
|
||||
#
|
||||
# The name to use. Defaults to Anonymous.
|
||||
#
|
||||
name: "Anonymous"
|
||||
#
|
||||
# The UUID to use. Defaults to 606e2ff0-ed77-4842-9d6c-e1d3321c7838 (UUID of MHF_Question).
|
||||
#
|
||||
uuid: "606e2ff0-ed77-4842-9d6c-e1d3321c7838"
|
||||
|
||||
#
|
||||
# Should the Caching of players be disabled?
|
||||
#
|
||||
# When set to true will AdvancedServerList not load any players from the cache.data file (if present) nor save any to it.
|
||||
# Placeholders that rely on the player being cached (such as ${player name}) will not work while this option is enabled.
|
||||
#
|
||||
# Defaults to false when not present.
|
||||
#
|
||||
disableCache: false
|
||||
|
||||
#
|
||||
# Should AdvancedServerList check for new versions?
|
||||
#
|
||||
# When set to true will AdvancedServerList check for a new version on modrinth.com every 12 hours and inform you in the
|
||||
# console about whether it found any new update or not.
|
||||
#
|
||||
# Defaults to false when not present.
|
||||
#
|
||||
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
|
||||
```
|
||||
///
|
||||
|
||||
#### Additionally created files and folders
|
||||
|
||||
There are certain files and folders that get created when certain events happen:
|
||||
|
||||
- A `playercache.json` file will be created on plugin shutdown containing a list of IPs, UUIDs and Player names for every player that joined the server while AdvancedServerList was running.
|
||||
This file allows to replace `${player name}` and `${player uuid}` with their name or UUID respectively, while they are not on the server, by using the IP they used to join with.
|
||||
This file is not created nor updated when `disableCache` is set to `true` in the config.yml
|
||||
- A `backups` folder containing old config.yml files.
|
||||
This folder is created when AdvancedServerList migrates your old config to a new version. This allows you to transfer settings over in case the migration didn't work properly.
|
||||
|
||||
## 3. Creating your first profile { #creating-your-first-profile }
|
||||
|
||||
Creating your first profile is relatively simple.
|
||||
|
||||
To start, open the `default.yml` file located inside the `profiles` folder using a file editor of your choice (VSCode or Notepad++ are recommended). It should contain all the available options for a server list profile.
|
||||
Next can you edit the options available to whatever you like. All text options (Except [conditions](../profiles/index.md#conditions)) support [MiniMessage formatting](../profiles/formatting.md).
|
||||
|
||||
If you're unsure how a specific option should look like, head over to the [Profiles page](../profiles/index.md) for more information about the general structure.
|
||||
All you need to know is, that a bare-bones server list profile requires a valid [priority](../profiles/index.md#priority) and at least one of the settings to be present.
|
||||
|
||||
To give an example is here a basic profile that only modifies the MOTD and nothing else:
|
||||
```yaml title="default.yml"
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- 'Hello'
|
||||
- 'World!'
|
||||
```
|
||||
|
||||
### Additional profiles
|
||||
|
||||
To add additional profiles, create a new YAML file inside the `profiles` folder. The name doesn't matter, but it is recommended to keep it lowercase, use alphanumeric characters (`a-z, 0-9`), hyphens (`-`), underscores (`_`) and avoid spaces.
|
||||
|
||||
Inside the file, add a priority and at least one setting, similar to the above shown example.
|
||||
This would already be enough and AdvancedServerList would use it. If you however want to only show it when certain conditions are met, should you set the priority to a higher value and add conditions.
|
||||
|
||||
Conditions can be multiple strings containing [operands](../profiles/index.md#operands) to evaluate them. As an example `${server playersOnline} >= 10` would return true if the current number of online players is larger or equal to 10.
|
||||
|
||||
Here is another example profile using conditions:
|
||||
```yaml title="other_profile.yml"
|
||||
priority: 1
|
||||
|
||||
condition: '${player isBanned}'
|
||||
|
||||
motd:
|
||||
- '<red>You got <bold>banned</bold> from this server.'
|
||||
```
|
||||
|
||||
### Further examples
|
||||
|
||||
The [Examples page](../examples/index.md) contains more examples of different server list profiles for all kinds of situations.
|
||||
|
||||
## 4. Loading profiles { #loading-profiles }
|
||||
|
||||
Once you've set up your server list profile(s) is it time to load it/them.
|
||||
To do this, simply run `/asl reload` as player (Requires permission `advancedserverlist.admin` or `advancedserverlist.command.reload`) or through the Server/Proxy console.
|
||||
|
||||
The plugin should then load any valid YAML file inside the `profiles` folder to then use.
|
||||
|
||||
And that's already it! You now have a working server list profile for your server.
|
||||
+19
-15
@@ -24,13 +24,11 @@ If you're new to the plugin is it recommended to check out the [Profiles page](p
|
||||
|
||||
AdvancedServerList supports the following platforms:
|
||||
|
||||
[![spigot-img]{ width="64" loading="lazy" }][spigot]
|
||||
[![paper-img]{ width="64" loading="lazy" }][paper]
|
||||
[![bungeecord-img]{ width="64" loading="lazy" }][spigot]
|
||||
[![waterfall-img]{ width="64" loading="lazy" }][paper]
|
||||
[![velocity-img]{ width="64" loading="lazy" }][velocity]
|
||||
|
||||
[spigot-img]: https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/spigot_vector.svg "Tested on Spigot"
|
||||
[paper-img]: https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/paper_vector.svg "Tested on Paper"
|
||||
[bungeecord-img]: https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/bungeecord_vector.svg "Tested on BungeeCord"
|
||||
[waterfall-img]: https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/waterfall_vector.svg "Tested on Waterfall"
|
||||
@@ -42,30 +40,36 @@ AdvancedServerList supports the following platforms:
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Dependency | Platforms | Required? |
|
||||
|-------------------------------------------------------------------------|----------------------|-----------|
|
||||
| [ProtocolLib]{ target="_blank" rel="noreferrer nofollow noopener" } | Spigot | Yes |
|
||||
| [PlaceholderAPI]{ target="_blank" rel="noreferrer nofollow noopener" } | Spigot, Paper | No |
|
||||
| [ViaVersion]{ target="_blank" rel="noreferrer nofollow noopener" } | Spigot, Paper | No |
|
||||
| [PAPIProxyBridge]{ target="_blank" rel="noreferrer nofollow noopener" } | BungeeCord, Velocity | No |
|
||||
| [Maintenance]{ target="_blank" rel="noreferrer nofollow noopener" } | All | No |
|
||||
/// info
|
||||
All listed dependencies are optional.
|
||||
///
|
||||
|
||||
[protocollib]: https://www.spigotmc.org/resources/1997/
|
||||
[placeholderapi]: https://www.spigotmc.org/resources/6245/
|
||||
[viaversion]: https://www.spigotmc.org/resources/19254/
|
||||
| Dependency | Platforms |
|
||||
|-------------------------------------------------------------------------|----------------------|
|
||||
| [PlaceholderAPI]{ target="_blank" rel="noreferrer nofollow noopener" } | Paper |
|
||||
| [ViaVersion]{ target="_blank" rel="noreferrer nofollow noopener" } | Paper |
|
||||
| [PAPIProxyBridge]{ target="_blank" rel="noreferrer nofollow noopener" } | BungeeCord, Velocity |
|
||||
| [Maintenance]{ target="_blank" rel="noreferrer nofollow noopener" } | All |
|
||||
|
||||
[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
|
||||
|
||||
## Pages
|
||||
|
||||
- [Getting started](getting-started/index.md)
|
||||
- [Commands](commands/index.md)
|
||||
- [Profiles](profiles/index.md)
|
||||
- [Formatting](profiles/formatting.md)
|
||||
- [Placeholders](profiles/placeholders.md)
|
||||
- [API](api/index.md)
|
||||
- [Changelog](api/changelog.md)
|
||||
- [Reference](api/reference/index.md)
|
||||
- [Examples](examples/index.md)
|
||||
- [Migration](migration/index.md)
|
||||
- [v1.5.3 to v1.6.0](migration/v1_5_3-to-v1_6_0.md)
|
||||
- [v1.9.0 to v1.10.0](migration/v1_9_0-to-v1_10_0.md)
|
||||
- [API](api/index.md)
|
||||
- [Changelog](api/changelog.md)
|
||||
- [Javadocs](api/javadocs.md) (External site)
|
||||
- [Source Code](api/source.md) (External site)
|
||||
- [Reference](api/reference/index.md)
|
||||
- [PlaceholderAPI](placeholderapi/index.md)
|
||||
@@ -0,0 +1,7 @@
|
||||
nav:
|
||||
- index.md
|
||||
- v3_8_0-to-v3_9_0.md
|
||||
- v3_7_0-to-v3_8_0.md
|
||||
- pre-v3_7_0-to-v3_7_0.md
|
||||
- v1_9_0-to-v1_10_0.md
|
||||
- v1_5_3-to-v1_6_0.md
|
||||
Loaded 100 of 143 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user