Compare commits

...
78 Commits
Author SHA1 Message Date
Andre601 db93816e55 Remove configurate relocation in Velocity 2024-01-23 15:40:49 +01:00
Andre601 244c2440fc Add migration for pre 3.7.0 files 2024-01-20 22:27:43 +01:00
Andre601 8e2c644669 Merge pull request 'Update dependency org.junit.jupiter:junit-jupiter-engine to v5.10.1' (#213) from renovate/org.junit.jupiter-junit-jupiter-engine-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/213
2024-01-20 12:04:27 +00:00
Andre601 a68809ab31 Merge pull request 'Update dependency net.md-5:bungeecord-api to v1.20-R0.2' (#212) from renovate/net.md-5-bungeecord-api-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/212
2024-01-20 12:03:07 +00:00
Andre601's Renovate Bot 4b4fd80abe Update dependency org.junit.jupiter:junit-jupiter-engine to v5.10.1 2024-01-20 12:01:07 +00:00
Andre601's Renovate Bot 48ea128267 Update dependency net.md-5:bungeecord-api to v1.20-R0.2 2024-01-20 12:01:00 +00:00
Andre601 68e5795618 Link to new condition option 2024-01-19 15:37:27 +00:00
Andre601 1aa20e4196 Bump version to 3.7.0-b1 2024-01-19 16:10:56 +01:00
Andre601 6db25c8f9c Merge pull request 'Use BungeeTabListPlus inspired Condition system' (#209) from feature/use-btlp-condition-system into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/209
2024-01-19 15:06:30 +00:00
Andre601 0ef3db752d Improve docs 2024-01-19 16:05:54 +01:00
Andre601 1a26f5ad34 Merge branch 'master' into feature/use-btlp-condition-system 2024-01-19 14:51:10 +00:00
Andre601 17a5574be7 Fix placeholder issue (I hope) 2024-01-18 22:33:36 +01:00
Andre601 c7bfb8a736 Update examples and bump version 2024-01-18 14:29:54 +01:00
Andre601 7a756c3b98 Merge pull request 'Update actions/cache action to v4' (#211) from renovate/actions-cache-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/211
2024-01-18 12:09:07 +00:00
Andre601's Renovate Bot 1539e1c3c0 Update actions/cache action to v4 2024-01-18 12:01:20 +00:00
Andre601 a86872c021 Remove unused applyStringToStringFunction 2024-01-17 16:53:07 +01:00
Andre601 7d12499f39 Update docs and add basic tests 2024-01-17 16:48:35 +01:00
Andre601 455434b5f3 Merge pull request 'Update dependency net.william278:papiproxybridge to v1.5' (#210) from renovate/net.william278-papiproxybridge-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/210
2024-01-17 12:02:54 +00:00
Andre601's Renovate Bot b66251ab20 Update dependency net.william278:papiproxybridge to v1.5 2024-01-17 12:01:18 +00:00
Andre601 4a1dfa5cb4 Use dedicated Template class for errors. 2024-01-16 22:58:06 +01:00
Andre601 1efd65e16c Merge branch 'master' into feature/use-btlp-condition-system 2024-01-16 21:48:26 +00:00
Andre601 908da9cd32 Add some logging messages 2024-01-16 22:47:53 +01:00
Andre601 e8a30c6ef7 Use BungeeTabListPlus inspired Condition system 2024-01-16 22:23:24 +01:00
Andre601 df164c104f Merge pull request 'Update dependency mkdocs-material to v9.5.4' (#208) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/208
2024-01-15 12:02:23 +00:00
Andre601's Renovate Bot acdf6f6e9a Update dependency mkdocs-material to v9.5.4 2024-01-15 12:01:07 +00:00
Andre601 f52a63a8f1 Merge pull request 'Update dependency mkdocs-glightbox to v0.3.6' (#207) from renovate/mkdocs-glightbox-0.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/207
2023-12-31 14:14:03 +00:00
Andre601's Renovate Bot 6a92cb3a16 Update dependency mkdocs-glightbox to v0.3.6 2023-12-31 12:01:29 +00:00
Andre601 1175451753 Merge pull request 'Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.12.1' (#206) from renovate/org.apache.maven.plugins-maven-compiler-plugin-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/206
2023-12-25 13:39:01 +00:00
Andre601's Renovate Bot 5c4130411b Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.12.1 2023-12-25 12:02:04 +00:00
Andre601 05727eeec5 Merge pull request 'Update dependency mkdocs-material to v9.5.3' (#205) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/205
2023-12-24 13:02:23 +00:00
Andre601's Renovate Bot 10af949abc Update dependency mkdocs-material to v9.5.3 2023-12-24 12:01:33 +00:00
Andre601 9851347e74 Merge pull request 'Update dependency net.kyori:adventure-platform-bungeecord to v4.3.2' (#204) from renovate/net.kyori-adventure-platform-bungeecord-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/204
2023-12-22 12:06:31 +00:00
Andre601's Renovate Bot c3e01c8b9c Update dependency net.kyori:adventure-platform-bungeecord to v4.3.2 2023-12-22 12:01:07 +00:00
Andre601 a646d9e998 Merge pull request 'Update dependency com.google.guava:guava to v33' (#203) from renovate/com.google.guava-guava-33.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/203
2023-12-21 12:06:31 +00:00
Andre601's Renovate Bot 3c50a30d4a Update dependency com.google.guava:guava to v33 2023-12-21 12:01:11 +00:00
Andre601 4328ad6b44 Merge pull request 'Update actions/upload-pages-artifact action to v3' (#202) from renovate/actions-upload-pages-artifact-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/202
2023-12-20 12:18:17 +00:00
Andre601 34b0555508 Merge pull request 'Update actions/deploy-pages action to v4' (#201) from renovate/actions-deploy-pages-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/201
2023-12-20 12:18:04 +00:00
Andre601's Renovate Bot c92cd0058b Update actions/upload-pages-artifact action to v3 2023-12-20 12:01:05 +00:00
Andre601's Renovate Bot 2cfe8b8a27 Update actions/deploy-pages action to v4 2023-12-20 12:01:01 +00:00
Andre601 6530fed704 Merge pull request 'Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.12.0' (#200) from renovate/org.apache.maven.plugins-maven-compiler-plugin-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/200
2023-12-19 12:05:46 +00:00
Andre601 7efb203e7b Merge branch 'master' into renovate/org.apache.maven.plugins-maven-compiler-plugin-3.x 2023-12-19 12:05:24 +00:00
Andre601 1a34376100 Merge pull request 'Update dependency net.kyori:adventure-text-serializer-legacy to v4.15.0' (#199) from renovate/net.kyori-adventure-text-serializer-legacy-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/199
2023-12-19 12:05:00 +00:00
Andre601's Renovate Bot ec1aa5b393 Update dependency org.apache.maven.plugins:maven-compiler-plugin to v3.12.0 2023-12-19 12:01:42 +00:00
Andre601's Renovate Bot 9683d3c001 Update dependency net.kyori:adventure-text-serializer-legacy to v4.15.0 2023-12-19 12:01:30 +00:00
Andre601 db60545fcc Add 1.20.4 in ModrinthVersionUploader 2023-12-18 20:19:44 +01:00
Andre601 392495ef63 Merge pull request 'Update dependency net.kyori:adventure-text-minimessage to v4.15.0' (#198) from renovate/net.kyori-adventure-text-minimessage-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/198
2023-12-18 12:53:37 +00:00
Andre601 903764b234 Merge branch 'master' into renovate/net.kyori-adventure-text-minimessage-4.x 2023-12-18 12:53:18 +00:00
Andre601 72329ed1e4 Merge pull request 'Update dependency net.kyori:adventure-api to v4.15.0' (#197) from renovate/net.kyori-adventure-api-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/197
2023-12-18 12:53:04 +00:00
Andre601's Renovate Bot c516b56053 Update dependency net.kyori:adventure-text-minimessage to v4.15.0 2023-12-18 12:44:29 +00:00
Andre601's Renovate Bot 5e4295fbfb Update dependency net.kyori:adventure-api to v4.15.0 2023-12-18 12:44:20 +00:00
Andre601 b140c0aa32 Merge pull request 'Add debug option for log messages' (#194) from feature/add-debug into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/194
2023-12-15 19:55:08 +00:00
Andre601 8f7b293541 Merge branch 'master' into feature/add-debug 2023-12-15 19:50:01 +00:00
Andre601 6f878164c5 Add debug option to getting started guide. 2023-12-13 18:27:17 +00:00
Andre601 a16801ff56 Remove mention of spigot being tested 2023-12-13 18:25:41 +00:00
Andre601 65a89cf762 Merge branch 'master' into feature/add-debug 2023-12-12 22:01:57 +00:00
Andre601 27d4ada179 Merge pull request 'Update maven Docker tag to v3.9.6' (#196) from renovate/maven-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/196
2023-12-12 12:03:23 +00:00
Andre601 574edfb246 Merge branch 'master' into renovate/maven-3.x 2023-12-12 12:03:04 +00:00
Andre601 7b7aad9d4e Merge pull request 'Update dependency mkdocs-material to v9.5.2' (#195) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/195
2023-12-12 12:02:38 +00:00
Andre601's Renovate Bot c5c9ed8109 Update maven Docker tag to v3.9.6 2023-12-12 12:01:19 +00:00
Andre601's Renovate Bot 58fea4090d Update dependency mkdocs-material to v9.5.2 2023-12-12 12:01:11 +00:00
Andre601 cd0aad6ec1 Add debug option for log messages 2023-12-09 20:26:54 +01:00
Andre601 fa45844434 Merge pull request 'Update dependency mkdocs-material to v9.5.1' (#192) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/192
2023-12-08 12:28:41 +00:00
Andre601 c4e2a144b5 Merge pull request 'Update actions/setup-python action to v5' (#193) from renovate/actions-setup-python-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/193
2023-12-08 12:28:31 +00:00
Andre601's Renovate Bot 7fe93c7021 Update actions/setup-python action to v5 2023-12-08 12:01:09 +00:00
Andre601's Renovate Bot 1d413a5c2a Update dependency mkdocs-material to v9.5.1 2023-12-08 12:01:00 +00:00
Andre601 51db52dbdd Merge pull request 'Update dependency com.viaversion:viaversion-api to v4.9.2' (#190) from renovate/com.viaversion-viaversion-api-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/190
2023-12-07 12:07:24 +00:00
Andre601 4ade528188 Merge pull request 'Update dependency mkdocs-material to v9.5.0' (#191) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/191
2023-12-07 12:07:12 +00:00
Andre601's Renovate Bot 64ba48a7c7 Update dependency mkdocs-material to v9.5.0 2023-12-07 12:02:54 +00:00
Andre601's Renovate Bot ac4edb2b97 Update dependency com.viaversion:viaversion-api to v4.9.2 2023-12-07 12:02:49 +00:00
Andre601 3ea000c98b Merge pull request 'Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.3' (#189) from renovate/org.apache.httpcomponents.client5-httpclient5-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/189
2023-12-06 13:06:15 +00:00
Andre601 746bef13e1 Merge pull request 'Update dependency com.viaversion:viaversion-api to v4.9.1' (#188) from renovate/com.viaversion-viaversion-api-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/188
2023-12-06 13:06:01 +00:00
Andre601's Renovate Bot 355ab73546 Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.3 2023-12-06 12:01:10 +00:00
Andre601's Renovate Bot 67170c70e0 Update dependency com.viaversion:viaversion-api to v4.9.1 2023-12-06 12:01:07 +00:00
Andre601 f99c2df4e8 Merge pull request 'Update actions/configure-pages action to v4' (#186) from renovate/actions-configure-pages-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/186
2023-12-05 12:12:05 +00:00
Andre601 212ec04fb8 Merge pull request 'Update actions/deploy-pages action to v3' (#187) from renovate/actions-deploy-pages-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/187
2023-12-05 12:11:49 +00:00
Andre601's Renovate Bot 89c6089101 Update actions/deploy-pages action to v3 2023-12-05 12:01:17 +00:00
Andre601's Renovate Bot 87bce39d9a Update actions/configure-pages action to v4 2023-12-05 12:01:12 +00:00
Andre601 18900547a0 Remove leading and trailing whitespaces from server names 2023-12-05 01:46:45 +01:00
91 changed files with 3711 additions and 118 deletions

No files matched your search

+5 -5
View File
@@ -24,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
@@ -39,11 +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
id: deployment
uses: actions/deploy-pages@v2
uses: actions/deploy-pages@v4
+1 -1
View File
@@ -4,7 +4,7 @@ when:
steps:
createFiles:
image: maven:3.9.5-eclipse-temurin-17
image: maven:3.9.6-eclipse-temurin-17
secrets:
- source: cb_token
target: codeberg_api_token
+1 -1
View File
@@ -98,7 +98,7 @@ 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/
+6 -6
View File
@@ -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.1</version>
<version>4.3.2</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -128,7 +128,7 @@
<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>
@@ -46,7 +46,7 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
private AdvancedServerList<Favicon> core;
private FaviconHandler<Favicon> faviconHandler = null;
private final PluginLogger logger = new BungeeLogger(getLogger());
private final PluginLogger logger = new BungeeLogger(this);
@Override
public void onEnable(){
@@ -25,6 +25,7 @@
package ch.andre601.advancedserverlist.bungeecord.logging;
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import java.util.logging.Level;
@@ -32,10 +33,24 @@ import java.util.logging.Logger;
public class BungeeLogger implements PluginLogger{
private final BungeeCordCore plugin;
private final Logger logger;
public BungeeLogger(Logger logger){
this.logger = logger;
public BungeeLogger(BungeeCordCore plugin){
this.plugin = plugin;
this.logger = plugin.getLogger();
}
@Override
public void debug(Class<?> clazz, String msg, Object... args){
if(plugin.isDebugEnabled())
info("[DEBUG] [" + clazz.getSimpleName() + "] " + msg, args);
}
@Override
public void debugWarn(Class<?> clazz, String msg, Object... args){
if(plugin.isDebugEnabled())
warn("[DEBUG] [" + clazz.getSimpleName() + "] " + msg, args);
}
@Override
@@ -60,7 +60,7 @@ public class BungeeServerPlaceholders extends PlaceholderProvider{
if(serverName.isEmpty())
continue;
ServerInfo info = proxy.getServers().get(serverName);
ServerInfo info = proxy.getServers().get(serverName.strip());
if(info == null)
continue;
+14 -9
View File
@@ -41,6 +41,7 @@
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<plugin.config.version>3</plugin.config.version>
</properties>
<repositories>
@@ -71,22 +72,24 @@
<version>4.1.2</version>
<scope>provided</scope>
</dependency>
<!-- MiniMessage -->
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.14.0</version>
<version>4.15.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.14.0</version>
<version>4.15.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-legacy</artifactId>
<version>4.14.0</version>
<version>4.15.0</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -110,13 +113,15 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
<version>33.0.0-jre</version>
<scope>provided</scope>
</dependency>
<!-- Plugins -->
<dependency>
<groupId>net.william278</groupId>
<artifactId>papiproxybridge</artifactId>
<version>1.4.2</version>
<version>1.5</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -128,9 +133,9 @@
<!-- Test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
</dependencies>
@@ -147,7 +152,7 @@
<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>
@@ -31,6 +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.profiles.conditions.expressions.ExpressionEngine;
import ch.andre601.advancedserverlist.core.profiles.players.PlayerHandler;
import java.io.IOException;
@@ -47,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;
@@ -91,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();
@@ -136,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;
@@ -81,10 +81,12 @@ public class UpdateChecker{
logger.warn("Failed to look for any updates. See previous messages for reasons.");
return;
}
logger.debug(UpdateChecker.class, "Comparing versions...");
int result = version.compare(core.getVersion());
switch(result){
case -1 -> printUpdateBanner(version.getVersionNumber(), version.getId(), version.isRelease());
case -1 -> printUpdateBanner(version);
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?",
@@ -119,21 +121,31 @@ public class UpdateChecker{
private CompletableFuture<ModrinthVersion> checkUpdate(){
return CompletableFuture.supplyAsync(() -> {
PluginLogger logger = core.getPlugin().getPluginLogger();
String finalUrl = String.format(url, loader);
logger.debug(UpdateChecker.class, "Looking for updates on '%s'...", finalUrl);
if(core.getVersion().equals("UNKNOWN")){
logger.warn("Cannot perform Update check! Plugin version couldn't be parsed.");
return null;
}
Request request = new Request.Builder()
.url(String.format(url, loader))
.url(finalUrl)
.header("User-Agent", "AdvancedServerList-" + loader + "/" + core.getVersion())
.build();
logger.debug(UpdateChecker.class, "Connecting to website...");
try(Response response = client.newCall(request).execute()){
logger.debug(UpdateChecker.class, "Connected! Checking response code...");
if(!response.isSuccessful()){
logger.warn("Encountered a non-successful response from Modrinth! Code: %d", response.code());
return null;
}
logger.debug(UpdateChecker.class, "Received positive response code '%d'", response.code());
ResponseBody body = response.body();
if(body == null){
@@ -147,6 +159,8 @@ public class UpdateChecker{
return null;
}
logger.debug(UpdateChecker.class, "Received non-empty response body. Parsing it from JSON Array...");
List<ModrinthVersion> list = gson.fromJson(responseString, listType);
if(list == null || list.isEmpty()){
logger.warn("Couldn't convert JSON Array into a valid list.");
@@ -155,11 +169,15 @@ public class UpdateChecker{
ModrinthVersion version = list.get(0);
logger.debug(UpdateChecker.class, "Found entry '%s'", version);
if(version.getVersionNumber() == null || version.getVersionNumber().isEmpty()){
logger.warn("Cannot check latest version. Received version number was null/empty.");
return null;
}
logger.debug(UpdateChecker.class, "Successfully parsed version!");
return version;
}catch(JsonSyntaxException ex){
logger.warn("Encountered invalid JSON from Response body!", ex);
@@ -171,22 +189,22 @@ public class UpdateChecker{
});
}
private void printUpdateBanner(String version, String versionId, boolean isRelease){
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 version: %s", version.getVersionNumber());
logger.info("");
if(!isRelease){
if(!version.isRelease()){
logger.info("WARNING: This release is an Alpha/Beta! It may contain");
logger.info(" breaking changes!");
logger.info("");
}
logger.info("You can download the latest release from here:");
logger.info("https://modrinth.com/plugin/advancedserverlist/version/%s", versionId);
logger.info("https://modrinth.com/plugin/advancedserverlist/version/%s", version.getId());
logger.info("==================================================================");
}
@@ -219,5 +237,10 @@ public class UpdateChecker{
public int compare(String version){
return FlexVerComparator.compare(version, versionNumber);
}
@Override
public String toString(){
return String.format("ModrinthVersion{id=%s,versionNumber=%s,versionType=%s}", id, versionNumber, versionNumber);
}
}
}
@@ -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");
}
}
@@ -30,16 +30,22 @@ import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.conditions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionEngine;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionErrorTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.StringJoiner;
public class ServerListProfile{
private final int priority;
private final String condition;
private final List<Expression> expressions;
private final ProfileEntry defaultProfile;
@@ -47,8 +53,9 @@ public class ServerListProfile{
private final Random random = new Random();
public ServerListProfile(int priority, List<Expression> expressions, ProfileEntry defaultProfile, List<ProfileEntry> profiles){
public ServerListProfile(int priority, String condition, List<Expression> expressions, ProfileEntry defaultProfile, List<ProfileEntry> profiles){
this.priority = priority;
this.condition = condition;
this.expressions = expressions;
this.defaultProfile = defaultProfile;
@@ -59,7 +66,17 @@ public class ServerListProfile{
return priority;
}
public boolean evalConditions(GenericPlayer player, GenericServer server){
public boolean evalConditions(ExpressionEngine expressionEngine, PluginLogger logger, GenericPlayer player, GenericServer server){
if(condition != null && !condition.isEmpty()){
ExpressionTemplate template = expressionEngine.compile(condition, logger, player, server);
if(template instanceof ExpressionErrorTemplate errorTemplate){
logger.warn(errorTemplate.instantiateWithStringResult().evaluate());
return true;
}
return template.instantiateWithBooleanResult().evaluate();
}
if(expressions.isEmpty())
return true;
@@ -121,6 +138,7 @@ public class ServerListProfile{
private final PluginLogger logger;
private String condition = null;
private List<ProfileEntry> profiles = new ArrayList<>();
private ProfileEntry defaultProfile = ProfileEntry.empty();
@@ -133,11 +151,21 @@ public class ServerListProfile{
public static Builder resolve(String fileName, ConfigurationNode node, PluginLogger logger){
return new Builder(fileName, node, logger)
.resolveCondition()
.resolveExpressions()
.resolveProfiles()
.resolveDefaultProfile();
}
private Builder resolveCondition(){
String condition = node.node("condition").getString();
if(condition == null || condition.isEmpty())
return this;
this.condition = condition;
return this;
}
private Builder resolveExpressions(){
List<String> temp;
try{
@@ -150,6 +178,8 @@ public class ServerListProfile{
if(temp == null || temp.isEmpty())
return this;
StringJoiner joiner = new StringJoiner(" and ");
for(String str : temp){
Expression expr = Expression.resolve(str);
@@ -158,9 +188,18 @@ public class ServerListProfile{
continue;
}
joiner.add(str);
this.expressions.add(expr);
}
if(!this.expressions.isEmpty()){
logger.warn("'%s' uses 'conditions' which is deprecated in favour of the newer 'condition' option.", fileName);
logger.warn("The 'conditions' option will be removed in a future version.");
logger.warn("");
logger.warn("Please migrate your condition(s) over from the old option to the new option like this:");
logger.warn("consition: '%s'", joiner.toString());
}
return this;
}
@@ -184,7 +223,7 @@ public class ServerListProfile{
}
public ServerListProfile build(){
return new ServerListProfile(this.priority, this.expressions, this.defaultProfile, this.profiles);
return new ServerListProfile(this.priority, this.condition, this.expressions, this.defaultProfile, this.profiles);
}
}
}
@@ -0,0 +1,107 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.AbstractUnaryToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.AbstractUnaryToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.AbstractUnaryToStringExpression;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
public class Conversions{
private final static NumberFormat NUMBER_FORMAT;
static {
NUMBER_FORMAT = NumberFormat.getNumberInstance(Locale.ROOT);
NUMBER_FORMAT.setGroupingUsed(false);
}
public static ToBooleanExpression toBoolean(ToDoubleExpression expression){
return new AbstractUnaryToBooleanExpression<>(expression) {
@Override
public boolean evaluate(){
return delegate.evaluate() != 0;
}
};
}
public static ToBooleanExpression toBoolean(ToStringExpression expression){
return new AbstractUnaryToBooleanExpression<>(expression) {
@Override
public boolean evaluate(){
return Boolean.parseBoolean(delegate.evaluate());
}
};
}
public static ToDoubleExpression toDouble(ToBooleanExpression expression){
return new AbstractUnaryToDoubleExpression<>(expression) {
@Override
public double evaluate(){
return delegate.evaluate() ? 1 : 0;
}
};
}
public static ToDoubleExpression toDouble(ToStringExpression expression){
return new AbstractUnaryToDoubleExpression<>(expression) {
@Override
public double evaluate(){
String result = delegate.evaluate();
try{
return NUMBER_FORMAT.parse(result).doubleValue();
}catch(ParseException | NumberFormatException ex){
return 0;
}
}
};
}
public static ToStringExpression toString(ToBooleanExpression expression){
return new AbstractUnaryToStringExpression<>(expression) {
@Override
public String evaluate(){
return Boolean.toString(delegate.evaluate());
}
};
}
public static ToStringExpression toString(ToDoubleExpression expression){
return new AbstractUnaryToStringExpression<>(expression) {
@Override
public String evaluate(){
double result = delegate.evaluate();
return result == (int)result ? Integer.toString((int)result) : Double.toString(result);
}
};
}
}
@@ -0,0 +1,78 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers.TokenReader;
import com.google.common.collect.Ordering;
import java.text.ParsePosition;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class ExpressionTokenizer{
private static final Ordering<TokenReader> TOKEN_READER_ORDERING = Ordering.from(Comparator.comparingInt(TokenReader::getPriority)).reverse();
private final List<TokenReader> tokenReaders;
public ExpressionTokenizer(Iterable<TokenReader> tokenReaders){
this.tokenReaders = TOKEN_READER_ORDERING.immutableSortedCopy(tokenReaders);
}
public List<Token> parse(String text, PluginLogger logger, GenericPlayer player, GenericServer server){
ParsePosition position = new ParsePosition(0);
List<Token> tokens = new LinkedList<>();
next_token:
while(true){
while(position.getIndex() < text.length() && Character.isWhitespace(text.charAt(position.getIndex()))){
position.setIndex(position.getIndex() + 1);
}
if(position.getIndex() >= text.length())
break;
for(TokenReader tokenReader : tokenReaders){
Token token;
if(null != (token = tokenReader.read(text, position, player, server))){
tokens.add(token);
continue next_token;
}
}
logger.warn("Illegal token '%c' at index %d.", text.charAt(position.getIndex()), position.getIndex());
break;
}
return tokens;
}
}
@@ -0,0 +1,28 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
public interface Expression{}
@@ -0,0 +1,170 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.conditions.ExpressionTokenizer;
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.ListOperator;
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.Operator;
import ch.andre601.advancedserverlist.core.profiles.conditions.parsers.*;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.BooleanToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.DefaultTokens;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers.*;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ExpressionEngine{
private final ExpressionTokenizer tokenizer;
private final ExpressionTemplateParser templateParser;
public ExpressionEngine(){
Options options = new Options.Builder()
.withDefaultTokenReaders()
.withDefaultOperators()
.withDefaultValueReaders()
.build();
this.tokenizer = new ExpressionTokenizer(options.tokenReaders);
this.templateParser = new ExpressionTemplateParser(options.operators, options.valueReaders);
}
public ExpressionTemplate compile(String expression, PluginLogger logger, GenericPlayer player, GenericServer server){
return templateParser.parse(tokenizer.parse(expression, logger, player, server));
}
public static class Options{
private final List<TokenReader> tokenReaders;
private final ImmutableMap<Token, Operator> operators;
private final ImmutableList<ValueReader> valueReaders;
private Options(List<TokenReader> tokenReaders, ImmutableMap<Token, Operator> operators, ImmutableList<ValueReader> valueReaders){
this.tokenReaders = tokenReaders;
this.operators = operators;
this.valueReaders = valueReaders;
}
public static class Builder{
private final List<TokenReader> tokenReaders = new ArrayList<>();
private final Map<Token, Operator> operators = new HashMap<>();
private final List<ValueReader> valueReaders = new ArrayList<>();
public Builder(){}
public Builder withDefaultTokenReaders(){
return this
.tokenReader(new PatternTokenReader(BooleanToken.FALSE, "false"))
.tokenReader(new PatternTokenReader(BooleanToken.TRUE, "true"))
.tokenReader(new PatternTokenReader(DefaultTokens.AND, "and"))
.tokenReader(new PatternTokenReader(DefaultTokens.AND, "&&"))
.tokenReader(new PatternTokenReader(DefaultTokens.OR, "or"))
.tokenReader(new PatternTokenReader(DefaultTokens.OR, "||"))
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL, "=="))
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL, "="))
.tokenReader(new PatternTokenReader(DefaultTokens.NOT_EQUAL, "!="))
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL_IGNORE_CASE, "~="))
.tokenReader(new PatternTokenReader(DefaultTokens.NOT_EQUAL_IGNORE_CASE, "!~"))
.tokenReader(new PatternTokenReader(DefaultTokens.GREATER_OR_EQUAL_THAN, ">="))
.tokenReader(new PatternTokenReader(DefaultTokens.LESSER_OR_EQUAL_THAN, "<="))
.tokenReader(new PatternTokenReader(DefaultTokens.OPENING_PARENTHESIS, "("))
.tokenReader(new PatternTokenReader(DefaultTokens.CLOSING_PARENTHESIS, ")"))
.tokenReader(new PatternTokenReader(DefaultTokens.NEGATION, "!"))
.tokenReader(new PatternTokenReader(DefaultTokens.GREATER_THAN, ">"))
.tokenReader(new PatternTokenReader(DefaultTokens.LESSER_THAN, "<"))
.tokenReader(new PatternTokenReader(DefaultTokens.CONCAT_STRING, "."))
.tokenReader(new PatternTokenReader(DefaultTokens.ADD, "+"))
.tokenReader(new PatternTokenReader(DefaultTokens.SUB, "-"))
.tokenReader(new PatternTokenReader(DefaultTokens.MULT, "*"))
.tokenReader(new PatternTokenReader(DefaultTokens.DIV, "/"))
.tokenReader(new QuotedLiteralTokenReader(-10, '\"'))
.tokenReader(new QuotedLiteralTokenReader(-10, '\''))
.tokenReader(new PlaceholderTokenReader(-20))
.tokenReader(new NumberTokenReader(-50))
.tokenReader(new NonQuotedLiteralTokenReader(-100));
}
public Builder withDefaultOperators(){
return this
.operator(DefaultTokens.AND, ListOperator.of(100, ExpressionTemplates::and))
.operator(DefaultTokens.OR, ListOperator.of(50, ExpressionTemplates::or))
.operator(DefaultTokens.EQUAL, Operator.of(25, ExpressionTemplates::equal))
.operator(DefaultTokens.NOT_EQUAL, Operator.of(25, ExpressionTemplates::notEqual))
.operator(DefaultTokens.EQUAL_IGNORE_CASE, Operator.of(25, ExpressionTemplates::equalIgnoreCase))
.operator(DefaultTokens.NOT_EQUAL_IGNORE_CASE, Operator.of(25, ExpressionTemplates::notEqualIgnoreCase))
.operator(DefaultTokens.GREATER_THAN, Operator.of(25, ExpressionTemplates::greater))
.operator(DefaultTokens.GREATER_OR_EQUAL_THAN, Operator.of(25, ExpressionTemplates::greaterOrEqual))
.operator(DefaultTokens.LESSER_THAN, Operator.of(25, ExpressionTemplates::less))
.operator(DefaultTokens.LESSER_OR_EQUAL_THAN, Operator.of(25, ExpressionTemplates::lessOrEqual))
.operator(DefaultTokens.CONCAT_STRING, ListOperator.of(10, ExpressionTemplates::concat))
.operator(DefaultTokens.ADD, ListOperator.of(4, ExpressionTemplates::sum))
.operator(DefaultTokens.SUB, Operator.of(3, ExpressionTemplates::sub))
.operator(DefaultTokens.MULT, ListOperator.of(2, ExpressionTemplates::product))
.operator(DefaultTokens.DIV, Operator.of(1, ExpressionTemplates::div));
}
public Builder withDefaultValueReaders(){
return this
.valueReader(new BooleanConstantReader())
.valueReader(new NumberConstantReader())
.valueReader(new StringConstantReader())
.valueReader(new NegatedExpressionReader(DefaultTokens.NEGATION))
.valueReader(new ParenthesisedExpressionReader(DefaultTokens.OPENING_PARENTHESIS, DefaultTokens.CLOSING_PARENTHESIS))
.valueReader(new PlaceholderReader())
.valueReader(new NegatedNumberReader(DefaultTokens.SUB));
}
public Builder tokenReader(TokenReader tokenReader){
this.tokenReaders.add(tokenReader);
return this;
}
public Builder operator(Token token, Operator operator){
this.operators.put(token, operator);
return this;
}
public Builder valueReader(ValueReader valueReader){
this.valueReaders.add(valueReader);
return this;
}
public Options build(){
return new Options(this.tokenReaders, ImmutableMap.copyOf(operators), ImmutableList.copyOf(valueReaders));
}
}
}
}
@@ -0,0 +1,211 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.*;
import java.util.Collection;
public class Expressions{
public static ToBooleanExpression negate(ToBooleanExpression expression){
return new AbstractUnaryToBooleanExpression<>(expression) {
@Override
public boolean evaluate(){
return !delegate.evaluate();
}
};
}
public static ToBooleanExpression and(Collection<ToBooleanExpression> operands){
return new AbstractToBooleanExpression<>(operands) {
@Override
public boolean evaluate(){
for(ToBooleanExpression operand : operands){
if(!operand.evaluate())
return false;
}
return true;
}
};
}
public static ToBooleanExpression or(Collection<ToBooleanExpression> operands){
return new AbstractToBooleanExpression<>(operands) {
@Override
public boolean evaluate(){
for(ToBooleanExpression operand : operands){
if(operand.evaluate())
return true;
}
return false;
}
};
}
public static ToStringExpression concat(Collection<ToStringExpression> operands){
return new AbstractToStringExpression<>(operands) {
@Override
public String evaluate(){
StringBuilder result = new StringBuilder();
for(ToStringExpression operand : operands){
result.append(operand.evaluate());
}
return result.toString();
}
};
}
public static ToBooleanExpression equal(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return a.evaluate().equals(b.evaluate());
}
};
}
public static ToBooleanExpression notEqual(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return !a.evaluate().equals(b.evaluate());
}
};
}
public static ToBooleanExpression equalIgnoreCase(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return a.evaluate().equalsIgnoreCase(b.evaluate());
}
};
}
public static ToBooleanExpression notEqualIgnoreCase(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return !a.evaluate().equalsIgnoreCase(b.evaluate());
}
};
}
public static ToBooleanExpression greaterThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return a.evaluate() > b.evaluate();
}
};
}
public static ToBooleanExpression greaterOrEqualThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return a.evaluate() >= b.evaluate();
}
};
}
public static ToBooleanExpression lessThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return a.evaluate() < b.evaluate();
}
};
}
public static ToBooleanExpression lessOrEqualThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
@Override
public boolean evaluate(){
return a.evaluate() <= b.evaluate();
}
};
}
public static ToDoubleExpression sum(Collection<ToDoubleExpression> operands){
return new AbstractToDoubleExpression<>(operands) {
@Override
public double evaluate(){
double result = 0;
for(ToDoubleExpression operand : operands){
result += operand.evaluate();
}
return result;
}
};
}
public static ToDoubleExpression product(Collection<ToDoubleExpression> operands){
return new AbstractToDoubleExpression<>(operands) {
@Override
public double evaluate(){
double result = 1;
for(ToDoubleExpression operand : operands){
result *= operand.evaluate();
}
return result;
}
};
}
public static ToDoubleExpression sub(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToDoubleExpression<>(a, b) {
@Override
public double evaluate(){
return a.evaluate() - b.evaluate();
}
};
}
public static ToDoubleExpression div(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToDoubleExpression<>(a, b) {
@Override
public double evaluate(){
return a.evaluate() / b.evaluate();
}
};
}
public static ToDoubleExpression negateNumber(ToDoubleExpression a){
return new AbstractUnaryToDoubleExpression<>(a) {
@Override
public double evaluate(){
return -delegate.evaluate();
}
};
}
}
@@ -0,0 +1,49 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
public interface ToBooleanExpression extends Expression{
boolean evaluate();
static ToBooleanExpression literal(boolean value){
return new ConstantToBooleanExpression(value);
}
class ConstantToBooleanExpression implements ToBooleanExpression{
private final boolean value;
public ConstantToBooleanExpression(boolean value){
this.value = value;
}
@Override
public boolean evaluate(){
return value;
}
}
}
@@ -0,0 +1,49 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
public interface ToDoubleExpression extends Expression{
double evaluate();
static ToDoubleExpression literal(double value){
return new ConstantToDoubleExpression(value);
}
class ConstantToDoubleExpression implements ToDoubleExpression{
private final double value;
public ConstantToDoubleExpression(double value){
this.value = value;
}
@Override
public double evaluate(){
return value;
}
}
}
@@ -0,0 +1,49 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
public interface ToStringExpression extends Expression{
String evaluate();
static ToStringExpression literal(String value){
return new ConstantToStringExpression(value);
}
class ConstantToStringExpression implements ToStringExpression{
private final String value;
private ConstantToStringExpression(String value){
this.value = value;
}
@Override
public String evaluate(){
return value;
}
}
}
@@ -0,0 +1,56 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.operators;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
public abstract class ListOperator extends Operator{
public ListOperator(int priority){
super(priority);
}
public static ListOperator of(int priority, Function<Collection<ExpressionTemplate>, ExpressionTemplate> function){
return new ListOperator(priority){
@Override
public ExpressionTemplate createTemplate(List<ExpressionTemplate> operands){
return function.apply(operands);
}
};
}
@Override
public ExpressionTemplate createTemplate(ExpressionTemplate a, ExpressionTemplate b){
return createTemplate(Arrays.asList(a, b));
}
public abstract ExpressionTemplate createTemplate(List<ExpressionTemplate> operands);
}
@@ -0,0 +1,54 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.operators;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import java.util.function.BiFunction;
public abstract class Operator{
private final int priority;
public Operator(int priority){
this.priority = priority;
}
public static Operator of(int priority, BiFunction<ExpressionTemplate, ExpressionTemplate, ExpressionTemplate> function){
return new Operator(priority){
@Override
public ExpressionTemplate createTemplate(ExpressionTemplate a, ExpressionTemplate b){
return function.apply(a, b);
}
};
}
public int getPriority(){
return priority;
}
public abstract ExpressionTemplate createTemplate(ExpressionTemplate a, ExpressionTemplate b);
}
@@ -0,0 +1,44 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ConstantExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.BooleanToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.List;
public class BooleanConstantReader extends ValueReader{
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) instanceof BooleanToken){
return ConstantExpressionTemplate.of(((BooleanToken)tokenList.remove(0)).getValue());
}
return null;
}
}
@@ -0,0 +1,133 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.ListOperator;
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.Operator;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionErrorTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.List;
public class ExpressionTemplateParser{
private final ImmutableMap<Token, Operator> operators;
private final ImmutableList<ValueReader> valueReaders;
public ExpressionTemplateParser(ImmutableMap<Token, Operator> operators, ImmutableList<ValueReader> valueReaders){
this.operators = operators;
this.valueReaders = valueReaders;
}
public ExpressionTemplate parse(List<Token> tokenList){
List<ExpressionTemplate> parts = new ArrayList<>();
List<Operator> operators = new ArrayList<>();
try{
parts.add(read(tokenList));
}catch(IllegalArgumentException ex){
return ExpressionErrorTemplate.of(ex.getMessage());
}
while(!tokenList.isEmpty()){
Token token = tokenList.remove(0);
Operator operator = this.operators.get(token);
if(operator == null){
return ExpressionErrorTemplate.of("Error while parsing Expression. Got \"" + token + "\" but expected OPERATOR.");
}
operators.add(operator);
if(tokenList.isEmpty()){
return ExpressionErrorTemplate.of("Received unexpected end of input.");
}
try{
parts.add(read(tokenList));
}catch(IllegalArgumentException ex){
return ExpressionErrorTemplate.of(ex.getMessage());
}
}
while(!operators.isEmpty()){
Operator operator = operators.get(0);
int lowest = operator.getPriority();
int start = 0;
int end = 1;
for(int i = 1; i < operators.size(); i++){
operator = operators.get(i);
if(operator.getPriority() < lowest){
lowest = operator.getPriority();
start = i;
end = i + 1;
}else
if(operator.getPriority() > lowest){
break;
}else{
end++;
}
}
operator = operators.get(start);
ExpressionTemplate replacement;
if(start + 1 == end){
replacement = operator.createTemplate(parts.get(start), parts.get(end));
}else
if(operator instanceof ListOperator listOperator){
replacement = listOperator.createTemplate(new ArrayList<>(parts.subList(start, end + 1)));
}else{
List<ExpressionTemplate> conditions = new ArrayList<>(end - start);
for(int i = start; i < end; i++)
conditions.add(operators.get(i).createTemplate(parts.get(i), parts.get(i + 1)));
replacement = ExpressionTemplates.and(conditions);
}
for(int i = start; i < end; i++){
parts.remove(start);
operators.remove(start);
}
parts.set(start, replacement);
}
return parts.get(0);
}
ExpressionTemplate read(List<Token> tokenList){
for(ValueReader valueReader : valueReaders){
ExpressionTemplate template = valueReader.read(this, tokenList);
if(template != null)
return template;
}
throw new IllegalArgumentException("Invalid Expression. Expected literal but got token \"" + tokenList.get(0).toString() + "\"");
}
}
@@ -0,0 +1,51 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.List;
public class NegatedExpressionReader extends ValueReader{
private final Token tokenNegation;
public NegatedExpressionReader(Token tokenNegation){
this.tokenNegation = tokenNegation;
}
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) == tokenNegation){
tokenList.remove(0);
return ExpressionTemplates.negate(parser.read(tokenList));
}
return null;
}
}
@@ -0,0 +1,51 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.List;
public class NegatedNumberReader extends ValueReader{
private final Token tokenNegation;
public NegatedNumberReader(Token tokenNegation){
this.tokenNegation = tokenNegation;
}
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) == tokenNegation){
tokenList.remove(0);
return ExpressionTemplates.negateNumber(parser.read(tokenList));
}
return null;
}
}
@@ -0,0 +1,43 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ConstantExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.NumberToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.List;
public class NumberConstantReader extends ValueReader{
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) instanceof NumberToken){
return ConstantExpressionTemplate.of(((NumberToken)tokenList.remove(0)).getValue());
}
return null;
}
}
@@ -0,0 +1,71 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.ArrayList;
import java.util.List;
public class ParenthesisedExpressionReader extends ValueReader{
private final Token openingParenthesis;
private final Token closingParenthesis;
public ParenthesisedExpressionReader(Token openingParenthesis, Token closingParenthesis){
this.openingParenthesis = openingParenthesis;
this.closingParenthesis = closingParenthesis;
}
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) == openingParenthesis){
int index = 0;
int cnt = 1;
do {
index += 1;
if(tokenList.size() <= index)
return null;
Token token = tokenList.get(index);
if(token == openingParenthesis){
cnt++;
}else
if(token == closingParenthesis){
cnt--;
}
}while(cnt != 0);
ExpressionTemplate result = parser.parse(new ArrayList<>(tokenList.subList(1, index)));
tokenList.subList(0, index + 1).clear();
return result;
}
return null;
}
}
@@ -0,0 +1,43 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.PlaceholderToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.List;
public class PlaceholderReader extends ValueReader{
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) instanceof PlaceholderToken){
PlaceholderToken token = (PlaceholderToken)tokenList.remove(0);
return token.getValue();
}
return null;
}
}
@@ -0,0 +1,44 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ConstantExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.StringToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.List;
public class StringConstantReader extends ValueReader{
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) instanceof StringToken){
return ConstantExpressionTemplate.of(((StringToken)tokenList.remove(0)).getValue());
}
return null;
}
}
@@ -0,0 +1,36 @@
/*
* 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.List;
public abstract class ValueReader{
public abstract ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList);
}
@@ -0,0 +1,62 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.placeholders;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
public interface Placeholder extends ExpressionTemplate{
static LiteralPlaceholderValue of(String value){
return new LiteralPlaceholderValue(value);
}
class LiteralPlaceholderValue implements Placeholder{
private final String value;
public LiteralPlaceholderValue(String value){
this.value = value;
}
@Override
public ToStringExpression instantiateWithStringResult(){
return ToStringExpression.literal(value);
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return ToDoubleExpression.literal(value.length());
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return ToBooleanExpression.literal(Boolean.parseBoolean(value));
}
}
}
@@ -0,0 +1,111 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.placeholders;
import ch.andre601.advancedserverlist.api.AdvancedServerListAPI;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import java.text.ParsePosition;
public class PlaceholderParser{
public static Placeholder parse(String text, ParsePosition position, GenericPlayer player, GenericServer server){
AdvancedServerListAPI api = AdvancedServerListAPI.get();
int index = position.getIndex();
StringBuilder identifier = new StringBuilder();
StringBuilder values = new StringBuilder();
boolean identified = false;
boolean invalid = true;
char[] chars = text.substring(index).toCharArray();
for(final char c : chars){
index++;
if(c == '}'){
invalid = false;
break;
}
if(c == ' ' && !identified){
identified = true;
continue;
}
if(identified){
values.append(c);
}else{
identifier.append(c);
}
}
String identifierStr = identifier.toString();
String valuesStr = values.toString();
StringBuilder raw = new StringBuilder();
position.setIndex(index + 1);
if(invalid){
raw.append("${").append(identifierStr);
if(identified)
raw.append(' ').append(valuesStr);
return Placeholder.of(raw.toString());
}
PlaceholderProvider provider = api.retrievePlaceholderProvider(identifierStr);
if(provider == null){
raw.append("${").append(identifierStr);
if(identified)
raw.append(' ').append(valuesStr);
raw.append('}');
return Placeholder.of(raw.toString());
}
String replacement = provider.parsePlaceholder(valuesStr, player, server);
if(replacement == null){
raw.append("${").append(identifierStr);
if(identified)
raw.append(' ').append(valuesStr);
raw.append('}');
return Placeholder.of(raw.toString());
}
return Placeholder.of(replacement);
}
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
public abstract class AbstractBinaryToBooleanExpression<T extends Expression> implements ToBooleanExpression{
protected final T a;
protected final T b;
public AbstractBinaryToBooleanExpression(T a, T b){
this.a = a;
this.b = b;
}
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
public abstract class AbstractBinaryToDoubleExpression<T extends Expression> implements ToDoubleExpression{
protected final T a;
protected final T b;
public AbstractBinaryToDoubleExpression(T a, T b){
this.a = a;
this.b = b;
}
}
@@ -0,0 +1,43 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.Conversions;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
public abstract class AbstractBooleanExpressionTemplate implements ExpressionTemplate{
@Override
public ToStringExpression instantiateWithStringResult(){
return Conversions.toString(instantiateWithBooleanResult());
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Conversions.toDouble(instantiateWithBooleanResult());
}
}
@@ -0,0 +1,43 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.Conversions;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
public abstract class AbstractDoubleExpressionTemplate implements ExpressionTemplate{
@Override
public ToStringExpression instantiateWithStringResult(){
return Conversions.toString(instantiateWithDoubleResult());
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Conversions.toBoolean(instantiateWithDoubleResult());
}
}
@@ -0,0 +1,43 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.Conversions;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
public abstract class AbstractStringExpressionTemplate implements ExpressionTemplate{
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Conversions.toDouble(instantiateWithStringResult());
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Conversions.toBoolean(instantiateWithStringResult());
}
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import java.util.Collection;
public abstract class AbstractToBooleanExpression<T extends Expression> implements ToBooleanExpression{
protected final Collection<T> operands;
public AbstractToBooleanExpression(Collection<T> operands){
this.operands = operands;
}
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import java.util.Collection;
public abstract class AbstractToDoubleExpression<T extends Expression> implements ToDoubleExpression{
protected final Collection<T> operands;
public AbstractToDoubleExpression(Collection<T> operands){
this.operands = operands;
}
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
import java.util.Collection;
public abstract class AbstractToStringExpression<T extends Expression> implements ToStringExpression{
protected Collection<T> operands;
public AbstractToStringExpression(Collection<T> operands){
this.operands = operands;
}
}
@@ -0,0 +1,38 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
public abstract class AbstractUnaryToBooleanExpression<T extends Expression> implements ToBooleanExpression{
protected final T delegate;
public AbstractUnaryToBooleanExpression(T delegate){
this.delegate = delegate;
}
}
@@ -0,0 +1,38 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
public abstract class AbstractUnaryToDoubleExpression<T extends Expression> implements ToDoubleExpression{
protected final T delegate;
public AbstractUnaryToDoubleExpression(T delegate){
this.delegate = delegate;
}
}
@@ -0,0 +1,38 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
public abstract class AbstractUnaryToStringExpression<T extends Expression> implements ToStringExpression{
protected final T delegate;
public AbstractUnaryToStringExpression(T delegate){
this.delegate = delegate;
}
}
@@ -0,0 +1,77 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
public class ConstantExpressionTemplate implements ExpressionTemplate{
private final ToStringExpression stringExpression;
private final ToDoubleExpression doubleExpression;
private final ToBooleanExpression booleanExpression;
private ConstantExpressionTemplate(String stringValue, double doubleValue, boolean booleanValue){
this.stringExpression = ToStringExpression.literal(stringValue);
this.doubleExpression = ToDoubleExpression.literal(doubleValue);
this.booleanExpression = ToBooleanExpression.literal(booleanValue);
}
public static ConstantExpressionTemplate of(String stringValue){
double doubleValue;
try{
doubleValue = Double.parseDouble(stringValue);
}catch(NumberFormatException ex){
doubleValue = stringValue.length();
}
return new ConstantExpressionTemplate(stringValue, doubleValue, Boolean.parseBoolean(stringValue));
}
public static ConstantExpressionTemplate of(double doubleValue){
return new ConstantExpressionTemplate(((int)doubleValue) == doubleValue ? Integer.toString((int)doubleValue) : Double.toString(doubleValue), doubleValue, doubleValue != 0);
}
public static ConstantExpressionTemplate of(boolean booleanValue){
return new ConstantExpressionTemplate(Boolean.toString(booleanValue), booleanValue ? 1 : 0, booleanValue);
}
@Override
public ToStringExpression instantiateWithStringResult(){
return stringExpression;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return doubleExpression;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return booleanExpression;
}
}
@@ -0,0 +1,58 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
public class ExpressionErrorTemplate implements ExpressionTemplate{
private final String msg;
private ExpressionErrorTemplate(String msg){
this.msg = msg;
}
public static ExpressionErrorTemplate of(String msg){
return new ExpressionErrorTemplate(msg);
}
@Override
public ToStringExpression instantiateWithStringResult(){
return ToStringExpression.literal(msg);
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return ToDoubleExpression.literal(0);
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return ToBooleanExpression.literal(false);
}
}
@@ -0,0 +1,39 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
public interface ExpressionTemplate{
ToStringExpression instantiateWithStringResult();
ToDoubleExpression instantiateWithDoubleResult();
ToBooleanExpression instantiateWithBooleanResult();
}
@@ -0,0 +1,362 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expressions;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
import java.util.Collection;
public class ExpressionTemplates{
public static ExpressionTemplate negate(ExpressionTemplate template){
return new Negation(template);
}
public static ExpressionTemplate and(Collection<ExpressionTemplate> operands){
return new And(operands);
}
public static ExpressionTemplate or(Collection<ExpressionTemplate> operands){
return new Or(operands);
}
public static ExpressionTemplate concat(Collection<ExpressionTemplate> operands){
return new Concatenate(operands);
}
public static ExpressionTemplate equal(ExpressionTemplate a, ExpressionTemplate b){
return new Equal(a, b);
}
public static ExpressionTemplate notEqual(ExpressionTemplate a, ExpressionTemplate b){
return new NotEqual(a, b);
}
public static ExpressionTemplate equalIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
return new EqualIgnoreCase(a, b);
}
public static ExpressionTemplate notEqualIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
return new NotEqualIgnoreCase(a, b);
}
public static ExpressionTemplate greater(ExpressionTemplate a, ExpressionTemplate b){
return new Greater(a, b);
}
public static ExpressionTemplate greaterOrEqual(ExpressionTemplate a, ExpressionTemplate b){
return new GreaterOrEqual(a, b);
}
public static ExpressionTemplate less(ExpressionTemplate a, ExpressionTemplate b){
return new Less(a, b);
}
public static ExpressionTemplate lessOrEqual(ExpressionTemplate a, ExpressionTemplate b){
return new LessOrEqual(a, b);
}
public static ExpressionTemplate sum(Collection<ExpressionTemplate> operands){
return new Sum(operands);
}
public static ExpressionTemplate product(Collection<ExpressionTemplate> operands){
return new Product(operands);
}
public static ExpressionTemplate sub(ExpressionTemplate a, ExpressionTemplate b){
return new Sub(a, b);
}
public static ExpressionTemplate div(ExpressionTemplate a, ExpressionTemplate b){
return new Div(a, b);
}
public static ExpressionTemplate negateNumber(ExpressionTemplate template){
return new NegationNumber(template);
}
private static class Negation extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate template;
Negation(ExpressionTemplate template){
this.template = template;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.negate(template.instantiateWithBooleanResult());
}
}
private static class And extends AbstractBooleanExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
And(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.and(operands.stream().map(ExpressionTemplate::instantiateWithBooleanResult).toList());
}
}
private static class Or extends AbstractBooleanExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
Or(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.or(operands.stream().map(ExpressionTemplate::instantiateWithBooleanResult).toList());
}
}
private static class Concatenate extends AbstractStringExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
Concatenate(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToStringExpression instantiateWithStringResult(){
return Expressions.concat(operands.stream().map(ExpressionTemplate::instantiateWithStringResult).toList());
}
}
private static class Equal extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Equal(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.equal(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class NotEqual extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
NotEqual(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.notEqual(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class EqualIgnoreCase extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
EqualIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.equalIgnoreCase(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class NotEqualIgnoreCase extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
NotEqualIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.notEqualIgnoreCase(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class Greater extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Greater(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.greaterThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class GreaterOrEqual extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
GreaterOrEqual(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.greaterOrEqualThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class Less extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Less(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.lessThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class LessOrEqual extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
LessOrEqual(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.lessOrEqualThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class Sum extends AbstractDoubleExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
Sum(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.sum(operands.stream().map(ExpressionTemplate::instantiateWithDoubleResult).toList());
}
}
private static class Product extends AbstractDoubleExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
Product(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.product(operands.stream().map(ExpressionTemplate::instantiateWithDoubleResult).toList());
}
}
private static class Sub extends AbstractDoubleExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Sub(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.sub(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class Div extends AbstractDoubleExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Div(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.div(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class NegationNumber extends AbstractDoubleExpressionTemplate{
private final ExpressionTemplate template;
NegationNumber(ExpressionTemplate template){
this.template = template;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.negateNumber(template.instantiateWithDoubleResult());
}
}
}
@@ -0,0 +1,42 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens;
public class BooleanToken extends Token{
public static final BooleanToken TRUE = new BooleanToken(true);
public static final BooleanToken FALSE = new BooleanToken(false);
private final boolean value;
public BooleanToken(boolean value){
super("BOOLEAN(" + value + ")");
this.value = value;
}
public boolean getValue(){
return value;
}
}
@@ -0,0 +1,47 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens;
public class DefaultTokens{
public static final Token AND = new Token("AND");
public static final Token OR = new Token("OR");
public static final Token OPENING_PARENTHESIS = new Token("OPENING_PARENTHESIS");
public static final Token CLOSING_PARENTHESIS = new Token("CLOSING_PARENTHESIS");
public static final Token EQUAL = new Token("EQUAL");
public static final Token NOT_EQUAL = new Token("NOT_EQUAL");
public static final Token EQUAL_IGNORE_CASE = new Token("EQUAL_IGNORE_CASE");
public static final Token NOT_EQUAL_IGNORE_CASE = new Token("NOT_EQUAL_IGNORE_CASE");
public static final Token NEGATION = new Token("NEGATION");
public static final Token GREATER_THAN = new Token("GREATER_THAN");
public static final Token GREATER_OR_EQUAL_THAN = new Token("GREATER_OR_EQUAL_THAN");
public static final Token LESSER_THAN = new Token("LESSER_THAN");
public static final Token LESSER_OR_EQUAL_THAN = new Token("LESSER_OR_EQUAL_THAN");
public static final Token CONCAT_STRING = new Token("CONCAT_STRING");
public static final Token ADD = new Token("ADD");
public static final Token SUB = new Token("SUB");
public static final Token MULT = new Token("MULT");
public static final Token DIV = new Token("DIV");
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens;
public class NumberToken extends Token{
private final double value;
public NumberToken(double value){
super("NUMBER(" + value + ")");
this.value = value;
}
public double getValue(){
return value;
}
}
@@ -0,0 +1,42 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens;
import ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.Placeholder;
public class PlaceholderToken extends Token{
private final Placeholder value;
public PlaceholderToken(Placeholder value){
super("PLACEHOLDER");
this.value = value;
}
public Placeholder getValue(){
return value;
}
}
@@ -0,0 +1,40 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens;
public class StringToken extends Token{
private final String value;
public StringToken(String value){
super("STRING(" + value + ")");
this.value = value;
}
public String getValue(){
return value;
}
}
@@ -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 Token{
private final String id;
public Token(String id){
this.id = id;
}
@Override
public String toString(){
return id;
}
}
@@ -0,0 +1,53 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.StringToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.text.ParsePosition;
public class NonQuotedLiteralTokenReader extends TokenReader{
public NonQuotedLiteralTokenReader(int priority){
super(priority);
}
@Override
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
int startIndex = position.getIndex();
int index = position.getIndex();
while(++index < text.length() && !Character.isWhitespace(text.charAt(index)))
;
position.setIndex(index);
return new StringToken(text.substring(startIndex, position.getIndex()));
}
}
@@ -0,0 +1,55 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.NumberToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.util.Locale;
public class NumberTokenReader extends TokenReader{
private final NumberFormat format = NumberFormat.getInstance(Locale.ROOT);
public NumberTokenReader(int priority){
super(priority);
}
@Override
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
int previous = position.getIndex();
Number number = format.parse(text, position);
if(position.getIndex() != previous)
return new NumberToken(number.doubleValue());
return null;
}
}
@@ -0,0 +1,61 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.text.ParsePosition;
public class PatternTokenReader extends TokenReader{
private final Token token;
private final String pattern;
private final boolean ignoreCase;
public PatternTokenReader(Token token, String pattern){
this(token, pattern, true);
}
public PatternTokenReader(Token token, String pattern, boolean ignoreCase){
super(pattern.length());
this.token = token;
this.pattern = pattern;
this.ignoreCase = ignoreCase;
}
@Override
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
if(text.regionMatches(ignoreCase, position.getIndex(), pattern, 0, pattern.length())){
position.setIndex(position.getIndex() + pattern.length());
return token;
}
return null;
}
}
@@ -0,0 +1,50 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.PlaceholderParser;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.PlaceholderToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.text.ParsePosition;
public class PlaceholderTokenReader extends TokenReader{
public PlaceholderTokenReader(int priority){
super(priority);
}
@Override
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
if(position.getIndex() + 1 < text.length() && text.charAt(position.getIndex()) == '$' && text.charAt(position.getIndex() + 1) == '{'){
position.setIndex(position.getIndex() + 2);
return new PlaceholderToken(PlaceholderParser.parse(text, position, player, server));
}
return null;
}
}
@@ -0,0 +1,62 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.StringToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.text.ParsePosition;
public class QuotedLiteralTokenReader extends TokenReader{
private final char quote;
public QuotedLiteralTokenReader(int priority, char quote){
super(priority);
this.quote = quote;
}
@Override
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
if(position.getIndex() < text.length() && text.charAt(position.getIndex()) == quote){
int startIndex = position.getIndex();
position.setIndex(position.getIndex() + 1);
while(position.getIndex() < text.length() && quote != text.charAt(position.getIndex()))
position.setIndex(position.getIndex() + 1);
position.setIndex(position.getIndex() + 1);
return new StringToken(text.substring(startIndex + 1, position.getIndex() - 1));
}
return null;
}
}
@@ -0,0 +1,47 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.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 abstract class TokenReader{
private final int priority;
public TokenReader(int priority){
this.priority = priority;
}
public int getPriority(){
return priority;
}
public abstract Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server);
}
@@ -70,21 +70,34 @@ public class FaviconHandler<F>{
private CompletableFuture<F> convert(String input, Function<BufferedImage, F> function){
return CompletableFuture.supplyAsync(() -> {
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Getting BufferedImage for input '%s'...", input);
BufferedImage img = resolveImage(core, input);
if(img == null)
if(img == null){
core.getPlugin().getPluginLogger().debugWarn(FaviconHandler.class, "No BufferedImage could be created!");
return null;
}
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Received BufferedImage! Applying it...");
return function.apply(img);
}, faviconThreadPool);
}
private BufferedImage resolveImage(AdvancedServerList<F> core, String input){
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resolving favicon for input '%s'...", input);
InputStream stream;
if(input.toLowerCase(Locale.ROOT).startsWith("https://")){
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "URL detected. Getting file from it...");
stream = getFromUrl(core, input);
}else
if(input.toLowerCase(Locale.ROOT).endsWith(".png")){
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Image file detected. Trying to reolve it...");
File folder = core.getPlugin().getFolderPath().resolve("favicons").toFile();
if(!folder.exists()){
core.getPlugin().getPluginLogger().warn("Cannot get Favicon %s from favicons folder. Folder doesn't exist!", input);
@@ -95,12 +108,16 @@ public class FaviconHandler<F>{
try{
stream = new FileInputStream(file);
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resolved image file!");
}catch(IOException ex){
core.getPlugin().getPluginLogger().warn("Cannot create Favicon from File %s.", input);
core.getPlugin().getPluginLogger().warn("Cause: %s", ex.getMessage());
return null;
}
}else{
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Possible player name/UUID detected. Using https://mc-heads.net/avatar/%s/64...", input);
stream = getFromUrl(core, "https://mc-heads.net/avatar/" + input + "/64");
}
@@ -116,6 +133,8 @@ public class FaviconHandler<F>{
return null;
}
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resizing image to 64x64 pixels...");
BufferedImage favicon = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
Graphics2D img = favicon.createGraphics();
@@ -123,6 +142,7 @@ public class FaviconHandler<F>{
img.drawImage(original, 0, 0, 64, 64, null);
img.dispose();
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Image resized!");
return favicon;
}catch(IOException ex){
core.getPlugin().getPluginLogger().warn("Unable to create Favicon. Encountered IOException during creation.");
@@ -133,11 +153,14 @@ public class FaviconHandler<F>{
private InputStream getFromUrl(AdvancedServerList<F> core, String url){
try{
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resolving URL '%s'...", url);
URL faviconUrl = new URL(url);
URLConnection connection = faviconUrl.openConnection();
connection.setRequestProperty("User-Agent", "AdvancedServerList/" + core.getVersion());
connection.connect();
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "URL resolved!");
return connection.getInputStream();
}catch(IOException ex){
core.getPlugin().getPluginLogger().warn("Error while connecting to %s for Favicon creation.", url);
@@ -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;
}
+12 -1
View File
@@ -31,10 +31,21 @@ disableCache: false
#
checkUpdates: true
#
# Should debug mode be enabled?
#
# When set to true will AdvancedServerList print additional messages to the console prefixed with "[DEBUG]".
# It is recommended to only enable this when having problems or when being told to by the plugin dev, as it could
# otherwise cause significant spam in your console.
#
# Defaults to false when not present.
#
debug: false
#
# DO NOT EDIT!
#
# This is used internally to determine if the config needs to be migrated.
# Changing or even removing this option could result in your config being broken.
#
config-version: 2
config-version: ${plugin.config.version}
@@ -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).
+2 -1
View File
@@ -23,4 +23,5 @@
#
#
version=${plugin.version}
version=${plugin.version}
config-version=${plugin.config.version}
@@ -0,0 +1,60 @@
/*
* 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.interfaces.PluginLogger;
public class DummyPluginLogger implements PluginLogger{
@Override
public void debug(Class<?> clazz, String msg, Object... args){
info("[DEBUG] [" + clazz.getSimpleName() + "] " + msg, args);
}
@Override
public void debugWarn(Class<?> clazz, String msg, Object... args){
warn("[DEBUG] [" + clazz.getSimpleName() + "] " + msg, args);
}
@Override
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,63 @@
/*
* 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;
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()));
}
}
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);
}
}
+13 -12
View File
@@ -25,18 +25,19 @@ def on_page_markdown(
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")
else: return _admo(text = args)
if type == "abstract": return _admo(text = args, type = "abstract")
elif type == "info": return _admo(text = args, type = "info")
elif type == "tip": return _admo(text = args, type = "tip")
elif type == "success": return _admo(text = args, type = "success")
elif type == "question": return _admo(text = args, type = "question")
elif type == "warning": return _admo(text = args, type = "warning")
elif type == "failure": return _admo(text = args, type = "failure")
elif type == "danger": return _admo(text = args, type = "danger")
elif type == "bug": return _admo(text = args, type = "bug")
elif type == "example": return _admo(text = args, type = "example")
elif type == "quote": return _admo(text = args, type = "quote")
elif type == "deprecated": return _admo(text = args, type = "deprecated")
else: return _admo(text = args)
# Otherwise, raise an error
raise RuntimeError(f"Unknown shortcode: {type}")
+20 -1
View File
@@ -23,11 +23,13 @@
--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="M14.265 1.627c0 3.545 1.869 5.327 3.479 7.021 1.54 1.62 3.006 3.163 3.006 6.102 0 4.812-3.753 8.25-8.565 8.25-4.813 0-8.935-3.421-8.935-8.25 0-2.039.962-4.011 2.509-4.899.305-.175.672.007.803.334C7.563 12.684 8.797 12.64 9.437 12c.388-.387.47-1.116-.004-2.062-2.405-4.812 1.863-8.279 4.2-8.854.336-.082.615.198.632.543ZM12.185 21.5c4.059 0 7.065-2.84 7.065-6.75 0-2.337-1.093-3.489-2.678-5.158l-.021-.023c-1.44-1.517-3.139-3.351-3.649-6.557a6.148 6.148 0 0 0-1.911 1.76c-.787 1.144-1.147 2.633-.216 4.495.603 1.205.777 2.74-.277 3.794-.657.657-1.762 1.1-2.956.586-.752-.324-1.353-.955-1.838-1.79-.567.706-.954 1.74-.954 2.893 0 3.847 3.288 6.75 7.435 6.75Z"></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>');
@@ -36,6 +38,7 @@
--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>');
}
/*
@@ -257,4 +260,20 @@
-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);
}
+7 -12
View File
@@ -6,7 +6,7 @@ icon: octicons/list-unordered-24
## About
<!-- admo:info 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.
@@ -38,8 +38,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 +56,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>!'
@@ -79,8 +77,7 @@ 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 +100,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 +114,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:
+18 -6
View File
@@ -25,12 +25,12 @@ The plugin is also available on these platforms, but not actively updated there
[spigot]: https://www.spigotmc.org/resources/102910/
[hangar]: https://hangar.papermc.io/Andre_601/AdvancedServerList
The plugin is available for Spigot, Paper, BungeeCord, Waterfall and Velocity, and has been tested on these platforms. It may support additional forks, but this is not guaranteed.
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. Depending on the platform they are used in is the plugin required.
The plugin also supports these additional plugins. They are all optional.
- [PlaceholderAPI] - Used on the Spigot and Paper server for additional Placeholder parsing.
- - [ViaVersion] - Used on the Spigot and Paper server for additional protocol version handling.
- [ViaVersion] - Used on the Paper server for additional protocol version handling.
- [PAPIProxyBridge] - Used on BungeeCord, Waterfall and Velocity for PlaceholderAPI support.
- [Maintenance] - Used to disable server list handling while maintenance is active.
@@ -46,11 +46,11 @@ Here is a quick table showing the jar file name with the platforms it is made fo
| Jar file name | Platforms |
|-----------------------------------------------|-----------------------|
| `AdvancedServerList-Paper-{version}.jar` | Spigot, Paper |
| `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 or need - (re)start your server or proxy to enable the plugin.
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
@@ -254,7 +254,8 @@ 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 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.
@@ -295,6 +296,17 @@ 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!
#
+56
View File
@@ -0,0 +1,56 @@
---
icon: octicons/arrow-right-24
---
# < 3.7.0 to 3.7.0
Version 3.7.0 of AdvancedServerList brought significant changes to its conditions system.
Namely, the `conditions` option is now deprecated and planned for removal in a future release of the Plugin, and the new [`condition`](../profiles/index.md#condition) option should now be used instead.
## Migration
To migrate, all you have to do is take the entries of the old conditions option and convert them into a single String connected with `and` operators in between. See the [Example below](#example).
## Example
Here is a before and after example to help visualize the change:
/// tab | Before
```yaml
priority: 0
conditions:
- '${player protocol} > 763'
- '${player isWhitelisted} == true'
motd:
- 'Welcome ${player name}!'
```
///
/// tab | After
```yaml
priority: 0
# The text can all be in one line. This is only for better readability.
condition: |
${player protocol} >= 763 and
${player isWhitelisted}
motd:
- 'Welcome ${player name}!'
```
///
/// tab | Diff View
```diff
priority: 0
-conditions:
- - '${player protocol} >= 763'
- - '${player isWhitelisted} == true'
+condition: |
+ ${player protocol} >= 763 and
+ ${player isWhitelisted}
```
///
+62 -14
View File
@@ -24,10 +24,58 @@ In order for a profile to be considered "valid" by AdvancedServerList will it ne
The priority option determines the order in which the profiles are checked by AdvancedServerList, starting with the highest number.
It will go through each file until it finds one with [`conditions`](#conditions) returning true (Default if no conditions are set).
It will go through each file until it finds one with [`condition`](#condition) returning true (Default if no conditions are set).
This means that a profile with no conditions and a priority of `1` will be used before a profile with a condition and priority `0` even if the player is meeting the condition.
## Conditions
## Condition
<!-- admo:tip Surround any text that is not an operand or placeholder in single or double quotes to avoid parsing errors. -->
A string containing one or multiple conditions chained together using the keywords `and` or `or` (Or alternatively `&&` or `||`).
The system used for conditions is adobted from BungeeTabListPlus.
/// details | Example
type: example
```yaml title="YAML file"
priority: 0
# Checks if the player is using 1.20 or newer AND is whitelisted
condition: |
${player protocol} >= 763 and
${player isWhitelisted}
motd:
- 'Welcome ${player name}!'
```
///
### Operands { #condition-operands }
The following operands can be used for expressions in the condition option.
| Operand | Description |
|--------------|------------------------------------------------------------------------------------------------------------------|
| `and` / `&&` | Returns true if the expression on the left and right side return true. |
| `or` / `||` | Returns true if an expression from either side returns true. |
| `()` | Expressions in-between those are prioritized in evaluation, starting with the most inner first. |
| `<` | Returns true if the left side is less than the right. In case of text will the text length be used. |
| `<=` | Returns true if the left side is less or equal to the right. In case of text will the text length be used. |
| `>` | Returns true if the left side is larger than the right. In case of text will the text length be used. |
| `>=` | Returns true if the left side is larger or equal to the right. In case of text will the text length be used. |
| `==` / `=` | Returns true if both sides are equal to each other. This also checks capitalization. |
| `!=` | Returns true if both sides are NOT equal to each other. This also checks capitalization. |
| `~=` | Returns true if both sides are equal to each other while also ignoring capitalization. |
| `!~` | Returns true if both sides are NOT equal to each other while also ignoring capitalization. |
| `.` | Merges two strings into one. |
| `+` | Adds two numbers together. In case of text will its text length be used as number. |
| `-` | Subtracts the value from the right from the left number. In case of text will its text length be used as number. |
| `*` | Multiplies two numbers together. In case of text will its text length be used as number. |
| `/` | Divides the left number through the right number. In case of text will its text length be used as number. |
## Conditions :octicons-trash-24:{ title="Deprecated" style="color: #ff5252;" }
<!-- admo:deprecated This option was deprecated in favour of the new condition option! -->
A list of conditions can be set that need to be met in order to have this profile shown to the player.
[Placeholders](formatting.md#placeholders) can be used to further customize the conditions (PlaceholderAPI placeholders are **not** supported).
@@ -36,22 +84,22 @@ Only when **all** conditions defined return true will the profile be displayed.
You can remove this option, or set it to an empty list (`conditions: []`) to always return true.
### Operands
### Operands { #conditions-operands }
The following operants are available and can be used in the conditions.
<!-- admo:warning Only one operant can be used per condition! -->
<!-- admo:warning For conditions option can you only use one operand per condition. -->
| Operand | Description |
|---------|------------------------------------------------------------------------|
| `<` | Checks if the left value is less than the right one.[^1] |
| `<=` | Checks if the left value is less than or equal to the right one.[^1] |
| `>` | Checks if the left value is more than the right one.[^1] |
| `>=` | Checks if the left value is more than or equal to the right one.[^1] |
| `=` | Checks if the left value is equal to the right one. |
| `!=` | Checks if the left value is not equal to the right one. |
| `~=` | Checks if the left value is equal to the right one, ignoring case. |
| `!~` | Checks if the left value is not equal to the right one, ignoring case. |
| Operand | Description |
|---------------|-------------------------------------------------------------------------|
| `<` | Checks if the left value is less than the right one.[^1] |
| `<=` | Checks if the left value is less than or equal to the right one.[^1] |
| `>` | Checks if the left value is more than the right one.[^1] |
| `>=` | Checks if the left value is more than or equal to the right one.[^1] |
| `=` | Checks if the left value is equal to the right one. |
| `!=` | Checks if the left value is not equal to the right one. |
| `~=` | Checks if the left value is equal to the right one, ignoring case. |
| `!~` | Checks if the left value is not equal to the right one, ignoring case. |
[^1]:
Should the provided value not be a number, will AdvancedServerList use the text length to compare.
+1
View File
@@ -29,6 +29,7 @@ theme:
- navigation.tabs
- navigation.tabs.sticky
- content.code.copy
- content.tooltips
icon:
repo: 'simple/codeberg'
+2 -2
View File
@@ -100,7 +100,7 @@
<dependency>
<groupId>com.viaversion</groupId>
<artifactId>viaversion-api</artifactId>
<version>4.8.1</version>
<version>4.9.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
@@ -117,7 +117,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<version>3.12.1</version>
<configuration>
<release>16</release>
</configuration>
@@ -46,7 +46,7 @@ import java.nio.file.Path;
public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon>{
private final PluginLogger logger = new PaperLogger(this.getLogger());
private final PluginLogger logger = new PaperLogger(this);
private AdvancedServerList<CachedServerIcon> core;
private FaviconHandler<CachedServerIcon> faviconHandler = null;
@@ -26,16 +26,31 @@
package ch.andre601.advancedserverlist.paper.logging;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.paper.PaperCore;
import java.util.logging.Level;
import java.util.logging.Logger;
public class PaperLogger implements PluginLogger{
private final PaperCore plugin;
private final Logger logger;
public PaperLogger(Logger logger){
this.logger = logger;
public PaperLogger(PaperCore 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
@@ -54,7 +54,7 @@ public class PaperServerPlaceholders extends PlaceholderProvider{
if(worldName.isEmpty())
continue;
World world = paperServer.worlds().get(worldName);
World world = paperServer.worlds().get(worldName.strip());
if(world == null)
continue;
+1 -1
View File
@@ -38,7 +38,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.commit/>
<plugin.version>3.6.0</plugin.version>
<plugin.version>3.7.0-b2</plugin.version>
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
<api.version>v3.1.0</api.version>
+2 -2
View File
@@ -1,4 +1,4 @@
mkdocs-material==9.4.14
mkdocs-glightbox==0.3.5
mkdocs-material==9.5.4
mkdocs-glightbox==0.3.6
mkdocs-awesome-pages-plugin==2.9.2
git+https://github.com/Andre601/mkdocs-pagenav-generator
+2 -6
View File
@@ -79,7 +79,7 @@
<groupId>org.spongepowered</groupId>
<artifactId>configurate-yaml</artifactId>
<version>4.1.2</version>
<scope>compile</scope>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
@@ -101,7 +101,7 @@
<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>
@@ -110,10 +110,6 @@
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>org.spongepowered.configurate</pattern>
<shadedPattern>ch.andre601.advancedserverlist.velocity.depends.configurate</shadedPattern>
</relocation>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>ch.andre601.advancedserverlist.velocity.depends.bstats</shadedPattern>
@@ -61,7 +61,7 @@ public class VelocityCore implements PluginCore<Favicon>{
@Inject
public VelocityCore(ProxyServer proxy, @DataDirectory Path path, Metrics.Factory metrics){
this.logger = new VelocityLogger(LoggerFactory.getLogger("AdvancedServerList"));
this.logger = new VelocityLogger(this, LoggerFactory.getLogger("AdvancedServerList"));
this.proxy = proxy;
this.path = path;
@@ -26,16 +26,31 @@
package ch.andre601.advancedserverlist.velocity.logging;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.velocity.VelocityCore;
import org.slf4j.Logger;
public class VelocityLogger implements PluginLogger{
private final VelocityCore plugin;
private final Logger logger;
public VelocityLogger(Logger logger){
public VelocityLogger(VelocityCore plugin, Logger logger){
this.plugin = plugin;
this.logger = logger;
}
@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
public void info(String msg, Object... args){
logger.info(String.format(msg, args));
@@ -58,7 +58,7 @@ public class VelocityServerPlaceholders extends PlaceholderProvider{
if(serverName.isEmpty())
continue;
RegisteredServer registeredServer = proxy.getServers().get(serverName);
RegisteredServer registeredServer = proxy.getServers().get(serverName.strip());
if(registeredServer == null)
continue;
+2 -2
View File
@@ -58,7 +58,7 @@
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2.3</version>
<version>5.3</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -87,7 +87,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<version>3.12.1</version>
<configuration>
<release>16</release>
</configuration>
@@ -51,7 +51,10 @@ public class ModrinthVersionUploader{
PlatformInfo.BUNGEECORD,
PlatformInfo.VELOCITY
);
private final List<String> versions = List.of("1.19", "1.19.1", "1.19.2", "1.19.3", "1.19.4", "1.20", "1.20.1", "1.20.2");
private final List<String> versions = List.of(
"1.19", "1.19.1", "1.19.2", "1.19.3", "1.19.4",
"1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4"
);
private final ModrinthAPI api;