Compare commits

...
65 Commits
Author SHA1 Message Date
Andre601 ba311f42c4 Use separated ExpressionParser system 2024-02-23 19:50:27 +01:00
Andre601 1b5379d54b Merge pull request 'Update dependency club.minnced:discord-webhooks to v0.8.4' (#231) from renovate/club.minnced-discord-webhooks-0.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/231
2024-02-23 12:02:14 +00:00
Andre601's Renovate Bot 03a1908ca6 Update dependency club.minnced:discord-webhooks to v0.8.4 2024-02-23 12:01:13 +00:00
Andre601 f9574d2f83 Add DISCORD_WEBHOOK_URL env variable to workflow 2024-02-22 13:42:41 +01:00
Andre601 7e45439dfe Merge pull request 'Make better local favicon handling' (#230) from feature/better-local-favicon-handling into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/230
2024-02-22 12:41:03 +00:00
Andre601 2a8b4ed640 Optimize Imports 2024-02-22 13:32:29 +01:00
Andre601 86c053e445 Remove unused createFavicon method in GenericEventWrapper 2024-02-22 13:29:39 +01:00
Andre601 7eba04bb9a Make better local favicon handling 2024-02-22 13:27:27 +01:00
Andre601 b4ac677f67 Merge pull request 'Update dependency org.apache.maven.plugins:maven-shade-plugin to v3.5.2' (#228) from renovate/org.apache.maven.plugins-maven-shade-plugin-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/228
2024-02-21 12:15:13 +00:00
Andre601 989d44cc5e Merge pull request 'Update dependency net.kyori:adventure-text-serializer-legacy to v4.16.0' (#229) from renovate/net.kyori-adventure-text-serializer-legacy-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/229
2024-02-21 12:15:00 +00:00
Andre601's Renovate Bot 9821875e7a Update dependency net.kyori:adventure-text-serializer-legacy to v4.16.0 2024-02-21 12:01:15 +00:00
Andre601's Renovate Bot 07e3b6702b Update dependency org.apache.maven.plugins:maven-shade-plugin to v3.5.2 2024-02-21 12:01:09 +00:00
Andre601 31889fbd9c Merge pull request 'Update dependency net.kyori:adventure-text-minimessage to v4.16.0' (#227) from renovate/net.kyori-adventure-text-minimessage-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/227
2024-02-20 12:12:40 +00:00
Andre601 87a089a0fa Merge pull request 'Update dependency net.kyori:adventure-api to v4.16.0' (#226) from renovate/net.kyori-adventure-api-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/226
2024-02-20 12:12:14 +00:00
Andre601 88b91e8859 Add AdvancedBan to special registry lookup 2024-02-20 12:09:55 +00:00
Andre601's Renovate Bot f8097e3c72 Update dependency net.kyori:adventure-text-minimessage to v4.16.0 2024-02-20 12:01:39 +00:00
Andre601's Renovate Bot e237c990d8 Update dependency net.kyori:adventure-api to v4.16.0 2024-02-20 12:01:33 +00:00
Andre601 21c0ba975c Merge pull request 'Update dependency mkdocs-material to v9.5.10' (#225) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/225
2024-02-19 12:02:37 +00:00
Andre601's Renovate Bot 642ce922c3 Update dependency mkdocs-material to v9.5.10 2024-02-19 12:01:15 +00:00
Andre601 6e5466aacf Use relativePath for pom.xml resolving 2024-02-18 23:47:09 +01:00
Andre601 e6635cd844 Fix wrong add-on name 2024-02-18 23:37:38 +01:00
Andre601 229ab60c57 Add ExpressionsWarnHelper for (hopefully) better warnings. 2024-02-18 23:23:06 +01:00
Andre601 483daee999 Merge pull request 'v4.0.0: AdvancedBan Addon' (#222) from feature/advanced-ban-addon into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/222
2024-02-18 20:45:42 +00:00
Andre601 31ffcd7f7b Add placeholders for mute and ban expiration dates 2024-02-18 17:44:16 +01:00
Andre601 e5139cc00d Slightly better wording for loaded placeholder sets 2024-02-18 15:35:55 +01:00
Andre601 9b1b95b27a Merge branch 'master' into feature/advanced-ban-addon 2024-02-18 14:33:37 +00:00
Andre601 88d3ceeaf3 Use PlatformInfo to store add-ons paths 2024-02-18 15:33:11 +01:00
Andre601 f74f2f337c Only supports 1.20+ on Paper 2024-02-18 15:22:53 +01:00
Andre601 87b35f240e Make the addon more generic and work on Paper too 2024-02-18 15:20:58 +01:00
Andre601 fc861ea304 Merge pull request 'Update api.version to v3.2.0' (#224) from renovate/api.version into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/224
2024-02-18 12:29:57 +00:00
Andre601's Renovate Bot 927971ca12 Update api.version to v3.2.0 2024-02-18 12:01:52 +00:00
Andre601 0ecb8383e3 Make the AdvancedBan Addon actually work. 2024-02-17 16:56:04 +01:00
Andre601 9c3b2220d5 Add some debug messages 2024-02-17 14:13:16 +01:00
Andre601 46e15441fd Merge pull request 'Update dependency ch.qos.logback:logback-classic to v1.5.0' (#223) from renovate/ch.qos.logback-logback-classic-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/223
2024-02-17 12:09:19 +00:00
Andre601's Renovate Bot 2d2a1ca805 Update dependency ch.qos.logback:logback-classic to v1.5.0 2024-02-17 12:01:07 +00:00
Andre601 c577264e1d Update documentation 2024-02-16 11:13:50 +01:00
Andre601 27c3972ab0 Bump to v4.0.0 and remove expressions 2024-02-16 11:03:48 +01:00
Andre601 e4c90730ba Add AdvancedBan Addon 2024-02-16 10:51:35 +01:00
Andre601 0694e08399 Remove unused import 2024-02-15 18:18:08 +01:00
Andre601 2fefa966dd Improve formatting page 2024-02-14 20:58:46 +01:00
Andre601 a57cf3df17 Update outdated info in get-started 2024-02-13 20:55:41 +00:00
Andre601 1ae7260cf3 Update Hangar status 2024-02-13 20:44:30 +00:00
Andre601 8459eee57d Fix wrong Modrinth ID. 2024-02-13 21:19:38 +01:00
Andre601 f5cebf42ab Change ~= to ~= 2024-02-13 21:05:52 +01:00
Andre601 731bdeba7d Change way of applying dependencies in ModrinthVersionUploader 2024-02-13 17:31:45 +01:00
Andre601 d14cda243a Bump mkdocs-material to 9.5.9 2024-02-10 14:23:29 +00:00
Andre601 0a98aad138 Use hook to remove backslash from | 2024-02-09 16:00:52 +01:00
Andre601 1249a08264 Make sure Anonymous is in double quotes. 2024-02-09 01:36:15 +00:00
Andre601 c0414a5962 Actually, starts with operator is better 2024-02-09 01:34:50 +00:00
Andre601 9cc4d4bb36 Add example for contains expression 2024-02-09 01:33:51 +00:00
Andre601 338358a2ab Why did it remove magiclink? 2024-02-09 01:23:41 +00:00
Andre601 805ba83bb6 fix typos and improve readme 2024-02-08 00:30:21 +00:00
Andre601 0f646a8f8d Merge pull request 'Update dependency mkdocs-material to v9.5.8' (#220) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/220
2024-02-07 12:31:20 +00:00
Andre601's Renovate Bot 2519f09f6f Update dependency mkdocs-material to v9.5.8 2024-02-07 12:01:04 +00:00
Andre601 60bca9e3d7 Redo getting started guide and migration page 2024-02-07 01:41:08 +01:00
Andre601 da8f72fc50 Update mkdocs.yml... I think 2024-02-07 01:06:06 +01:00
Andre601 c42d4b8967 Add operand examples and open original in new tab 2024-02-05 12:46:30 +00:00
Andre601 0110854ae4 Fix some typo 2024-02-04 19:20:01 +00:00
Andre601 d6d5952cbc Merge pull request 'Update dependency org.junit.jupiter:junit-jupiter-engine to v5.10.2' (#219) from renovate/org.junit.jupiter-junit-jupiter-engine-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/219
2024-02-04 12:54:07 +00:00
Andre601's Renovate Bot f9d961cae7 Update dependency org.junit.jupiter:junit-jupiter-engine to v5.10.2 2024-02-04 12:01:05 +00:00
Andre601 a387feea23 Fix wrong operand for contains in docs 2024-02-03 17:39:51 +01:00
Andre601 359c58163b Only add ViaVersion on paper platform. 2024-02-03 17:34:55 +01:00
Andre601 0892f5cd1d Use <_ for contains instead of <- 2024-02-03 17:21:54 +01:00
Andre601 452a7e6dcf Merge pull request 'Update dependency mkdocs-material to v9.5.7' (#218) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/218
2024-02-03 12:02:21 +00:00
Andre601's Renovate Bot 162dd10a73 Update dependency mkdocs-material to v9.5.7 2024-02-03 12:01:15 +00:00
109 changed files with 1638 additions and 3423 deletions

No files matched your search

+4 -1
View File
@@ -12,6 +12,8 @@ steps:
target: modrinth_api_token
- source: hangar_api_token
target: hangar_api_token
- source: discord_webhook_url
target: discord_webhook_url
commands:
# Create the jar files.
- mvn clean install
@@ -20,7 +22,7 @@ steps:
- mv VersionUploader.jar ../../
- cd ../../
# Execute Jar file
- java -jar VersionUploader.jar --modrinth
- java -jar VersionUploader.jar --all
uploadToCodeberg:
image: woodpeckerci/plugin-gitea-release
settings:
@@ -29,5 +31,6 @@ steps:
- "bungeecord/target/AdvancedServerList-*.jar"
- "paper/target/AdvancedServerList-*.jar"
- "velocity/target/AdvancedServerList-*.jar"
- "addons/banplugins/target/AdvancedServerList-*.jar"
api_key:
from_secret: CB_TOKEN
+8 -4
View File
@@ -1,6 +1,6 @@
# AdvancedServerList
AdvancedServerList is a plugin that allowys you to customize your server's MOTD, favicon, Player count text and player count hover displayed in a player's multiplayer server list based on conditions and priorities.
AdvancedServerList is a plugin that allows you to customize your server's MOTD, favicon, Player count text and player count hover displayed in a player's multiplayer server list based on conditions and priorities.
## Downloads
@@ -30,29 +30,33 @@ AdvancedServerList is a plugin that allowys you to customize your server's MOTD,
</a>
## What is a Server List Profile?
A Server List Profile refers to a YAML file located in the plugin's `profiles` directory.
It allows you to configure specific aspects of the server display in the MC-Client's multiplayer server list, such as the MOTD, player count text, player count hover or Favicon.
> [*Read More*][profiles]
### Conditions
Thanks to conditions can you determine when a profile should be displayed in the player’s server list, to allow displaying specific text (i.e. a warning when they are using an outdated version).
When multiple profiles exist that have valid conditions will the one with the highest priority (Higher number = higher priority) be selected. Having no conditions makes the profile automatically return true.
Thanks to conditions can you determine when a profile should be displayed in the player's server list, to allow displaying specific text (i.e. a warning when they are using an outdated version).
When multiple profiles exist that have valid conditions will the one with the highest priority (Higher number = higher priority) be selected. Having no conditions makes it automatically true.
> [*Read More*][conditions]
### Placeholders
Placeholders can be used within conditions to further customize them. They can also be used in any other text option to display their respective values.
The format is `${<target> <identifier>}` which was adopted from BungeeTabListPlus. Depending on what platform you use the plugin on are only specific placeholders available.
When using the SpigotMC/PaperMC version, or while PAPIProxyBridge is installed on your proxy, can you also use placeholders from [PlaceholderAPI][placeholderapi] using its `%<identifier>_<values>%` placeholder format. PlaceholderAPI needs to be installed for that.
When using the SpigotMC/PaperMC version, or while [PAPIProxyBridge][papiproxybridge] is installed on your proxy, can you also use placeholders from [PlaceholderAPI][placeholderapi] using its `%<identifier>_<values>%` placeholder format. PlaceholderAPI needs to be installed on the server (not proxy) for that.
If you're a plugin dev can you even add your own custom placeholders through AdvancedServerList's own API.
> [*Read More*][placeholders]
### Formatting
The plugin uses the MiniMessage format for a consistent, easy way of formatting your text.
Only certain options are usable for each option. As an example does motd support HEX colours and gradients, while the other options only support default colour codes.
+113
View File
@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>parent</artifactId>
<groupId>ch.andre601.advancedserverlist</groupId>
<version>parent</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>banplugins</artifactId>
<packaging>jar</packaging>
<version>${plugin.version}</version>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
<repository>
<id>papermc</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<!-- Proxy/Server -->
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<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.2</version>
<type>javadoc</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.20-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- Plugin APIs -->
<dependency>
<groupId>com.github.DevLeoko</groupId>
<artifactId>AdvancedBan</artifactId>
<version>v2.3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>api</artifactId>
<version>${api.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>AdvancedServerList-BanPlugins-Addon-${plugin.version}</finalName>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
</plugin>
</plugins>
</build>
</project>
@@ -23,27 +23,33 @@
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
package ch.andre601.advancedserverlist.banplugins.bungeecord;
public interface ToBooleanExpression extends Expression{
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.banplugins.placeholders.AdvancedBanPlaceholders;
import java.util.HashMap;
import java.util.Map;
public enum BungeeCordBanPlugins{
boolean evaluate();
ADVANCED_BAN("AdvancedBan", new AdvancedBanPlaceholders());
static ToBooleanExpression literal(boolean value){
return new ConstantToBooleanExpression(value);
private final String plugin;
private final PlaceholderProvider placeholderProvider;
BungeeCordBanPlugins(String plugin, PlaceholderProvider placeholderProvider){
this.plugin = plugin;
this.placeholderProvider = placeholderProvider;
}
class ConstantToBooleanExpression implements ToBooleanExpression{
public static Map<String, PlaceholderProvider> getBanPlugins(){
Map<String, PlaceholderProvider> content = new HashMap<>();
private final boolean value;
public ConstantToBooleanExpression(boolean value){
this.value = value;
for(BungeeCordBanPlugins bungeeCordBanPlugins : BungeeCordBanPlugins.values()){
content.put(bungeeCordBanPlugins.plugin, bungeeCordBanPlugins.placeholderProvider);
}
@Override
public boolean evaluate(){
return value;
}
return content;
}
}
@@ -0,0 +1,68 @@
/*
* 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.banplugins.bungeecord;
import ch.andre601.advancedserverlist.api.AdvancedServerListAPI;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import net.md_5.bungee.api.plugin.Plugin;
import java.util.Map;
public class BungeeCordBanPluginsAddon extends Plugin{
@Override
public void onEnable(){
if(getProxy().getPluginManager().getPlugin("AdvancedServerList") == null){
getLogger().warning("AdvancedServerList is not enabled. This plugin requires it to function!");
return;
}
int loadedPlaceholders = loadPlaceholderProviders();
if(loadedPlaceholders == 0){
getLogger().warning("No compatible Ban plugin was found to register placeholders for.");
}else{
getLogger().info("Loaded " + loadedPlaceholders + " Placeholder Set(s) for AdvancedServerList!");
}
}
private int loadPlaceholderProviders(){
int loaded = 0;
Map<String, PlaceholderProvider> banPlugins = BungeeCordBanPlugins.getBanPlugins();
AdvancedServerListAPI api = AdvancedServerListAPI.get();
for(Map.Entry<String, PlaceholderProvider> entry : banPlugins.entrySet()){
if(getProxy().getPluginManager().getPlugin(entry.getKey()) != null){
getLogger().info("Registering Placeholders for " + entry.getKey() + "...");
api.addPlaceholderProvider(entry.getValue());
getLogger().info("Placeholder successfully registered!");
loaded++;
}
}
return loaded;
}
}
@@ -23,27 +23,33 @@
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
package ch.andre601.advancedserverlist.banplugins.paper;
public interface ToDoubleExpression extends Expression{
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.banplugins.placeholders.AdvancedBanPlaceholders;
import java.util.HashMap;
import java.util.Map;
public enum PaperBanPlugins{
double evaluate();
ADVANCED_BAN("AdvancedBan", new AdvancedBanPlaceholders());
static ToDoubleExpression literal(double value){
return new ConstantToDoubleExpression(value);
private final String plugin;
private final PlaceholderProvider placeholderProvider;
PaperBanPlugins(String plugin, PlaceholderProvider placeholderProvider){
this.plugin = plugin;
this.placeholderProvider = placeholderProvider;
}
class ConstantToDoubleExpression implements ToDoubleExpression{
public static Map<String, PlaceholderProvider> getBanPlugins(){
Map<String, PlaceholderProvider> content = new HashMap<>();
private final double value;
public ConstantToDoubleExpression(double value){
this.value = value;
for(PaperBanPlugins paperBanPlugins : PaperBanPlugins.values()){
content.put(paperBanPlugins.plugin, paperBanPlugins.placeholderProvider);
}
@Override
public double evaluate(){
return value;
}
return content;
}
}
@@ -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.banplugins.paper;
import ch.andre601.advancedserverlist.api.AdvancedServerListAPI;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.Map;
public class PaperBanPluginsAddon extends JavaPlugin{
@Override
public void onEnable(){
if(!getServer().getPluginManager().isPluginEnabled("AdvancedServerList")){
getLogger().warning("AdvancedServerList is not enabled. This plugin requires it to function!");
getServer().getPluginManager().disablePlugin(this);
return;
}
int loadedPlaceholders = loadPlaceholderProviders();
if(loadedPlaceholders == 0){
getLogger().warning("No compatible Ban plugin was found to register placeholders for. Disabling plugin...");
getServer().getPluginManager().disablePlugin(this);
}else{
getLogger().info("Loaded " + loadedPlaceholders + " Placeholder Set(s) for AdvancedServerList!");
}
}
private int loadPlaceholderProviders(){
int loaded = 0;
Map<String, PlaceholderProvider> banPlugins = PaperBanPlugins.getBanPlugins();
AdvancedServerListAPI api = AdvancedServerListAPI.get();
for(Map.Entry<String, PlaceholderProvider> entry : banPlugins.entrySet()){
if(getServer().getPluginManager().isPluginEnabled(entry.getKey())){
getLogger().info("Registering Placeholders for " + entry.getKey() + "...");
api.addPlaceholderProvider(entry.getValue());
getLogger().info("Placeholder successfully registered!");
loaded++;
}
}
return loaded;
}
}
@@ -0,0 +1,96 @@
/*
* 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.banplugins.placeholders;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.banplugins.providers.AdvancedBanProvider;
import java.util.Arrays;
public class AdvancedBanPlaceholders extends PlaceholderProvider{
private final AdvancedBanProvider provider = new AdvancedBanProvider();
public AdvancedBanPlaceholders(){
super("advancedban");
}
@Override
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
String[] args = placeholder.split("\\s");
return switch(args[0]) {
// Mute-related placeholders
case "isMuted" -> String.valueOf(provider.muted(player));
case "muteReason" -> provider.muteReason(player);
case "muteDuration" -> {
if(args.length == 1)
yield provider.muteDuration(player);
if(args.length > 2)
yield null;
boolean fromStart = Boolean.getBoolean(args[1]);
yield provider.muteDuration(player, fromStart);
}
case "muteExpiration" -> {
if(args.length == 1)
yield provider.muteExpirationDate(player);
String pattern = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
yield provider.banExpirationDate(player, pattern);
}
// Ban-related placeholders
case "isBanned" -> String.valueOf(provider.banned(player));
case "banReason" -> provider.banReason(player);
case "banDuration" -> {
if(args.length == 1)
yield provider.banDuration(player);
if(args.length > 2)
yield null;
boolean fromStart = Boolean.getBoolean(args[1]);
yield provider.banDuration(player, fromStart);
}
case "banExpiration" -> {
if(args.length == 1)
yield provider.banExpirationDate(player);
String pattern = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
yield provider.banExpirationDate(player, pattern);
}
// Unknown/Invalid placeholder.
default -> null;
};
}
}
@@ -0,0 +1,141 @@
/*
* 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.banplugins.providers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import com.google.common.base.Strings;
import com.google.common.primitives.UnsignedLongs;
import me.leoko.advancedban.manager.PunishmentManager;
import me.leoko.advancedban.utils.Punishment;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
public class AdvancedBanProvider implements PunishmentProvider{
private static PunishmentManager getAPI(){
return PunishmentManager.get();
}
private static String noDashesUUID(UUID uuid){
return hexString(uuid.getMostSignificantBits()) + hexString(uuid.getLeastSignificantBits());
}
private static Punishment mute(GenericPlayer player){
return getAPI().getMute(noDashesUUID(player.getUUID()));
}
private static Punishment ban(GenericPlayer player){
return getAPI().getBan(noDashesUUID(player.getUUID()));
}
private static String hexString(long unsigned){
return Strings.padStart(UnsignedLongs.toString(unsigned, 16), 16, '0');
}
@Override
public boolean muted(GenericPlayer player){
return getAPI().isMuted(noDashesUUID(player.getUUID()));
}
@Override
public boolean banned(GenericPlayer player){
return getAPI().isBanned(noDashesUUID(player.getUUID()));
}
@Override
public String muteReason(GenericPlayer player){
Punishment mute = mute(player);
if(mute == null)
return null;
return mute.getReason();
}
@Override
public String banReason(GenericPlayer player){
Punishment ban = ban(player);
if(ban == null)
return null;
return ban.getReason();
}
@Override
public String muteDuration(GenericPlayer player){
return muteDuration(player, false);
}
@Override
public String banDuration(GenericPlayer player){
return banDuration(player, false);
}
@Override
public String muteExpirationDate(GenericPlayer player, String pattern){
Punishment mute = mute(player);
if(mute == null)
return null;
long end = mute.getEnd();
if(end < 0L)
return "never";
Date date = new Date(end);
return new SimpleDateFormat(pattern).format(date);
}
@Override
public String banExpirationDate(GenericPlayer player, String pattern){
Punishment ban = ban(player);
if(ban == null)
return null;
long end = ban.getEnd();
if(end < 0L)
return "never";
Date date = new Date(end);
return new SimpleDateFormat(pattern).format(date);
}
public String muteDuration(GenericPlayer player, boolean fromStart){
Punishment mute = mute(player);
if(mute == null)
return null;
return mute.getDuration(fromStart);
}
public String banDuration(GenericPlayer player, boolean fromStart){
Punishment ban = ban(player);
if(ban == null)
return null;
return ban.getDuration(fromStart);
}
}
@@ -23,32 +23,34 @@
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.operators;
package ch.andre601.advancedserverlist.banplugins.providers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import java.util.function.BiFunction;
public abstract class Operator{
public interface PunishmentProvider{
private final int priority;
boolean muted(GenericPlayer player);
public Operator(int priority){
this.priority = priority;
boolean banned(GenericPlayer player);
String muteReason(GenericPlayer player);
String banReason(GenericPlayer player);
String muteDuration(GenericPlayer player);
String banDuration(GenericPlayer player);
default String muteExpirationDate(GenericPlayer player){
return muteExpirationDate(player, "dd, MMM yyyy HH:mm:ss");
}
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);
}
};
String muteExpirationDate(GenericPlayer player, String pattern);
default String banExpirationDate(GenericPlayer player){
return banExpirationDate(player, "dd, MMM yyyy HH:mm:ss");
}
public int getPriority(){
return priority;
}
String banExpirationDate(GenericPlayer player, String pattern);
public abstract ExpressionTemplate createTemplate(ExpressionTemplate a, ExpressionTemplate b);
}
@@ -0,0 +1,10 @@
name: 'ASLBanPluginsAddon'
author: 'Andre_601'
version: '${plugin.version}'
description: 'AdvancedBan Add-on for AdvancedServerList to add placeholders to use.'
softDepends:
- AdvancedServerList
- AdvancedBan
main: 'ch.andre601.advancedserverlist.banplugins.bungeecord.BungeeCordBanPluginsAddon'
@@ -0,0 +1,16 @@
name: 'ASLBanPluginsAddon'
author: 'Andre_601'
version: '${plugin.version}'
main: 'ch.andre601.advancedserverlist.banplugins.paper.AdvancedBanPlaceholders'
api-version: '1.19'
dependencies:
server:
AdvancedServerList:
required: false
load: BEFORE
AdvancedBans:
required: false
load: BEFORE
+3 -3
View File
@@ -81,13 +81,13 @@
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.15.0</version>
<version>4.16.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.15.0</version>
<version>4.16.0</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -127,7 +127,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<version>3.5.2</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
@@ -40,6 +40,7 @@ import net.md_5.bungee.api.plugin.Plugin;
import org.bstats.bungeecord.Metrics;
import org.bstats.charts.SimplePie;
import java.awt.image.BufferedImage;
import java.nio.file.Path;
public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
@@ -77,12 +78,17 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
}
@Override
public void loadFaviconHandler(AdvancedServerList<Favicon> core){
faviconHandler = new FaviconHandler<>(core);
}
@Override
public void clearFaviconCache(){
if(faviconHandler == null)
return;
faviconHandler.clearCache();
faviconHandler.cleanCache();
}
@Override
@@ -122,4 +128,9 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
public String getLoader(){
return "bungeecord";
}
@Override
public Favicon createFavicon(BufferedImage image) throws IllegalArgumentException{
return Favicon.create(image);
}
}
@@ -25,11 +25,11 @@
package ch.andre601.advancedserverlist.bungeecord.listeners;
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
import ch.andre601.advancedserverlist.bungeecord.objects.BungeePlayerImpl;
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
import ch.andre601.advancedserverlist.bungeecord.objects.BungeeProxyImpl;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
@@ -46,7 +46,6 @@ import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.ProxyPingEvent;
import java.awt.image.BufferedImage;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.Map;
@@ -205,9 +204,4 @@ public class BungeeEventWrapper implements GenericEventWrapper<Favicon, BungeePl
return new BungeeProxyImpl(servers, playersOnline, playersMax, host);
}
@Override
public Favicon createFavicon(BufferedImage image) throws IllegalArgumentException{
return Favicon.create(image);
}
}
+16 -6
View File
@@ -41,7 +41,7 @@
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<plugin.config.version>3</plugin.config.version>
<plugin.config.version>4</plugin.config.version>
</properties>
<repositories>
@@ -66,6 +66,12 @@
<version>${api.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.andre601</groupId>
<artifactId>ExpressionParser</artifactId>
<version>v1.2.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.spongepowered</groupId>
<artifactId>configurate-yaml</artifactId>
@@ -77,19 +83,19 @@
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.15.0</version>
<version>4.16.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.15.0</version>
<version>4.16.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-legacy</artifactId>
<version>4.15.0</version>
<version>4.16.0</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -129,7 +135,7 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.1</version>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>
@@ -151,7 +157,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<version>3.5.2</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
@@ -168,6 +174,10 @@
<pattern>com.unascribed</pattern>
<shadedPattern>ch.andre601.advancedserverlist.core.depends.flexver</shadedPattern>
</relocation>
<relocation>
<pattern>ch.andre601.expressionparser</pattern>
<shadedPattern>ch.andre601.advancedserverlist.core.depends.expressionparser</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
@@ -31,12 +31,11 @@ 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.conditions.ProfileConditionParser;
import ch.andre601.advancedserverlist.core.profiles.players.PlayerHandler;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
@@ -48,7 +47,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 final ProfileConditionParser parser = ProfileConditionParser.create();
private UpdateChecker updateChecker;
@@ -93,8 +92,8 @@ public class AdvancedServerList<F>{
return api;
}
public ExpressionEngine getExpressionEngine(){
return expressionEngine;
public ProfileConditionParser getParser(){
return parser;
}
public void disable(){
@@ -148,9 +147,7 @@ public class AdvancedServerList<F>{
return;
}
Path folder = getPlugin().getFolderPath().resolve("favicons");
if(!folder.toFile().exists() && folder.toFile().mkdirs())
getPlugin().getPluginLogger().info("Successfully created favicons folder.");
getPlugin().loadFaviconHandler(this);
getPlugin().getPluginLogger().info("Loading Commands...");
plugin.loadCommands();
@@ -27,7 +27,10 @@ package ch.andre601.advancedserverlist.core.compat.papi;
import net.william278.papiproxybridge.api.PlaceholderAPI;
import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
@@ -30,10 +30,10 @@ 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.compat.papi.PAPIUtil;
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;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileManager;
@@ -148,26 +148,18 @@ public class PingEventHandler{
if(ProfileManager.checkOption(entry.favicon())){
logger.debug(PingEventHandler.class, "Favicon set. Resolving '%s'...", entry.favicon());
String favicon = StringReplacer.replace(entry.favicon(), player, server);
String faviconString = 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);
return null;
}
});
F favicon = plugin.getFaviconHandler().getFavicon(faviconString);
if(fav == null){
if(favicon == 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);
event.setFavicon(favicon);
}
}
@@ -46,18 +46,29 @@ public class ConfigMigrator{
public static ConfigurationTransformation.Versioned create(){
return ConfigurationTransformation.versionedBuilder()
.versionKey("configVersion")
.addVersion(LATEST, twoToThree())
.addVersion(LATEST, threeToFour())
.addVersion(3, twoToThree())
.addVersion(2, oneToTwo())
.build();
}
public static ConfigurationTransformation threeToFour(){
return ConfigurationTransformation.builder()
.addAction(NodePath.path(), (path, value) -> {
value.node("faviconCacheTime").set(1);
return null;
})
.build();
}
public static ConfigurationTransformation twoToThree(){
return ConfigurationTransformation.builder()
.addAction(NodePath.path(), ((path, value) -> {
.addAction(NodePath.path(), (path, value) -> {
value.node("debug").set(false);
return null;
}))
})
.build();
}
@@ -25,10 +25,10 @@
package ch.andre601.advancedserverlist.core.file;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileSerializer;
import org.spongepowered.configurate.ConfigurateException;
import org.spongepowered.configurate.ConfigurationNode;
@@ -165,7 +165,7 @@ public class FileHandler{
return false;
}
profiles.sort(Comparator.comparing(ServerListProfile::getPriority).reversed());
profiles.sort(Comparator.comparing(ServerListProfile::priority).reversed());
return !profiles.isEmpty();
}
@@ -191,6 +191,11 @@ public class FileHandler{
return node.node(path).getBoolean();
}
public long getLong(long def, long limit, Object... path){
long value = node.node(path).getLong(def);
return Math.max(value, limit);
}
public boolean isOldConfig(){
return node.node("configVersion").virtual() || node.node("configVersion").getInt(0) < ConfigMigrator.LATEST;
}
@@ -29,6 +29,7 @@ import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import java.awt.image.BufferedImage;
import java.nio.file.Path;
public interface PluginCore<F>{
@@ -39,6 +40,8 @@ public interface PluginCore<F>{
void loadMetrics();
void loadFaviconHandler(AdvancedServerList<F> core);
void clearFaviconCache();
AdvancedServerList<F> getCore();
@@ -55,7 +58,12 @@ public interface PluginCore<F>{
String getLoader();
F createFavicon(BufferedImage image) throws Exception;
default boolean isDebugEnabled(){
if(getCore() == null)
return false;
return getCore().getFileHandler().getBoolean("debug");
}
}
@@ -25,15 +25,14 @@
package ch.andre601.advancedserverlist.core.interfaces.events;
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import net.kyori.adventure.text.Component;
import java.awt.image.BufferedImage;
import java.net.InetSocketAddress;
import java.util.List;
@@ -79,8 +78,6 @@ public interface GenericEventWrapper<F, P extends GenericPlayer>{
GenericServer createGenericServer(int playersOnline, int playersMax, String host);
F createFavicon(BufferedImage image) throws Exception;
default String resolveHost(InetSocketAddress address){
return address == null ? null : address.getHostString();
}
@@ -29,63 +29,42 @@ import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.conditions.Expression;
import ch.andre601.advancedserverlist.core.profiles.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 ch.andre601.advancedserverlist.core.profiles.conditions.ProfileConditionParser;
import ch.andre601.expressionparser.ParseWarnCollector;
import ch.andre601.expressionparser.templates.ExpressionTemplate;
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{
public record ServerListProfile(int priority, String condition, ProfileEntry defaultProfile, List<ProfileEntry> profiles){
private static final Random random = new Random();
private final int priority;
private final String condition;
private final List<Expression> expressions;
private final ProfileEntry defaultProfile;
private final List<ProfileEntry> profiles;
private final Random random = new Random();
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;
this.profiles = profiles;
}
public int getPriority(){
return priority;
}
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())
public boolean evalConditions(ProfileConditionParser parser, PluginLogger logger, GenericPlayer player, GenericServer server){
if(condition == null || condition.isEmpty())
return true;
for(Expression expression : expressions){
if(!expression.evaluate(player, server))
return false;
ParseWarnCollector collector = new ParseWarnCollector(condition);
ExpressionTemplate template = parser.compile(condition, player, server, collector);
if(collector.hasWarnings()){
logger.warn("Encountered %d Error(s) while parsing condition '%s':", collector.getWarnings().size(), condition);
for(ParseWarnCollector.Context context : collector.getWarnings()){
if(context.position() <= -1){
logger.warn(" - %s", context.message());
}else{
logger.warn(" - At Position %d: %s", context.position(), context.message());
}
}
}
return true;
if(template == null)
return false;
return template.returnBooleanExpression().evaluate();
}
public ProfileEntry getRandomProfile(){
@@ -101,10 +80,6 @@ public class ServerListProfile{
}
}
public ProfileEntry getDefaultProfile(){
return defaultProfile;
}
/*
* Returns true if the Profile...
* ...doesn't have any valid MOTD set AND
@@ -113,12 +88,12 @@ public class ServerListProfile{
* ...doesn't have a favicon set.
*/
public boolean isInvalidProfile(){
if(profiles.isEmpty())
return defaultProfile.isInvalid();
if(profiles().isEmpty())
return defaultProfile().isInvalid();
boolean profilesValid = false;
for(ProfileEntry profile : profiles){
for(ProfileEntry profile : profiles()){
if(profile.isInvalid())
continue;
@@ -134,7 +109,6 @@ public class ServerListProfile{
private final String fileName;
private final ConfigurationNode node;
private final int priority;
private final List<Expression> expressions = new ArrayList<>();
private final PluginLogger logger;
@@ -152,7 +126,6 @@ public class ServerListProfile{
public static Builder resolve(String fileName, ConfigurationNode node, PluginLogger logger){
return new Builder(fileName, node, logger)
.resolveCondition()
.resolveExpressions()
.resolveProfiles()
.resolveDefaultProfile();
}
@@ -166,43 +139,6 @@ public class ServerListProfile{
return this;
}
private Builder resolveExpressions(){
List<String> temp;
try{
temp = node.node("conditions").getList(String.class);
}catch(SerializationException ex){
logger.warn("Encountered a SerializationException while resolving conditions for %s", ex, fileName);
return this;
}
if(temp == null || temp.isEmpty())
return this;
StringJoiner joiner = new StringJoiner(" and ");
for(String str : temp){
Expression expr = Expression.resolve(str);
if(expr.getResult() != Expression.ExpressionResult.VALID){
logger.warn("Found invalid expression in condition '%s'! Reason: %s", str, expr.getResult().getMessage());
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;
}
private Builder resolveProfiles(){
try{
this.profiles = node.node("profiles").getList(ProfileEntry.class);
@@ -223,7 +159,7 @@ public class ServerListProfile{
}
public ServerListProfile build(){
return new ServerListProfile(this.priority, this.condition, this.expressions, this.defaultProfile, this.profiles);
return new ServerListProfile(this.priority, this.condition, this.defaultProfile, this.profiles);
}
}
}
@@ -1,107 +0,0 @@
/*
* 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);
}
};
}
}
@@ -1,226 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
public class Expression{
private final ExpressionResult result;
private final String left;
private final Operator operator;
private final String right;
private Expression(ExpressionResult result, String left, Operator operator, String right){
this.result = result;
this.left = left;
this.operator = operator;
this.right = right;
}
public static Expression createInvalid(ExpressionResult result){
return new Expression(result, null, Operator.UNKNOWN, null);
}
public static Expression resolve(String expression){
Operator operator = Operator.UNKNOWN;
if(expression == null || expression.isEmpty()){
return Expression.createInvalid(ExpressionResult.INVALID_NO_EXPRESSION);
}
char[] chars = expression.toCharArray();
StringBuilder leftBuilder = new StringBuilder();
StringBuilder rightBuilder = new StringBuilder();
boolean foundOperator = false;
for(int i = 0; i < chars.length; i++){
char c = chars[i];
char next = (i == (chars.length - 1)) ? '\0' : chars[i + 1];
Operator tmp = Operator.getOperand(c, next);
if(tmp != Operator.UNKNOWN && !foundOperator){
operator = tmp;
foundOperator = true;
if(tmp.hasSecond())
i++; // Skip next character if operator has 2
continue;
}
if(foundOperator){
rightBuilder.append(c);
}else{
leftBuilder.append(c);
}
}
if(leftBuilder.isEmpty() || rightBuilder.isEmpty()){
return Expression.createInvalid(ExpressionResult.INVALID_EMPTY_PARTS);
}
return new Expression(ExpressionResult.VALID, leftBuilder.toString().trim(), operator, rightBuilder.toString().trim());
}
public boolean evaluate(GenericPlayer player, GenericServer server){
String newLeft = StringReplacer.replace(left, player, server);
String newRight = StringReplacer.replace(right, player, server);
return operator.evaluate(newLeft, newRight);
}
public ExpressionResult getResult(){
return result;
}
public enum Operator{
LESS('<', '\0'){
@Override
public boolean evaluate(String left, String right){
int leftInt = Operator.getInt(left);
int rightInt = Operator.getInt(right);
return leftInt < rightInt;
}
},
LESS_OR_EQUAL('<', '='){
@Override
public boolean evaluate(String left, String right){
int leftInt = Operator.getInt(left);
int rightInt = Operator.getInt(right);
return leftInt <= rightInt;
}
},
EQUAL('=', '\0'){
@Override
public boolean evaluate(String left, String right){
return left.equals(right);
}
},
EQUALS_IGNORE_CASE('~', '='){
@Override
public boolean evaluate(String left, String right){
return left.equalsIgnoreCase(right);
}
},
NOT_EQUAL('!', '='){
@Override
public boolean evaluate(String left, String right){
return !left.equals(right);
}
},
NOT_EQUAL_IGNORE_CASE('!', '~'){
@Override
public boolean evaluate(String left, String right){
return !left.equalsIgnoreCase(right);
}
},
GREATER('>', '\0'){
@Override
public boolean evaluate(String left, String right){
int leftInt = Operator.getInt(left);
int rightInt = Operator.getInt(right);
return leftInt > rightInt;
}
},
GREATER_OR_EQUAL('>', '='){
@Override
public boolean evaluate(String left, String right){
int leftInt = Operator.getInt(left);
int rightInt = Operator.getInt(right);
return leftInt >= rightInt;
}
},
UNKNOWN('\0', '\0'){
@Override
public boolean evaluate(String left, String right){
return false;
}
};
private static final Operator[] VALUES = values();
private final char first;
private final char second;
Operator(char first, char second){
this.first = first;
this.second = second;
}
public static Operator getOperand(char first, char second){
for(Operator operator : VALUES){
if(operator.first == first){
if((!operator.hasSecond() && second != '=' && second != '~') || operator.second == second)
return operator;
}
}
return Operator.UNKNOWN;
}
public boolean hasSecond(){
return second != '\0';
}
public abstract boolean evaluate(String left, String right);
private static int getInt(String text){
try{
return Integer.parseInt(text);
}catch(NumberFormatException ex){
return text.length();
}
}
}
public enum ExpressionResult{
VALID(null),
INVALID_NO_EXPRESSION("Received empty condition which isn't allowed!"),
INVALID_EMPTY_PARTS ("Received condition with either left or right part being empty.");
private final String message;
ExpressionResult(String message){
this.message = message;
}
public String getMessage(){
return message;
}
}
}
@@ -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.profiles.conditions.placeholders.reader.PlaceholderTokenReader;
import ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.reader.PlaceholderValueReader;
import ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.tokens.CustomExpressionTokenizer;
import ch.andre601.expressionparser.ExpressionParserEngine;
import ch.andre601.expressionparser.ParseWarnCollector;
import ch.andre601.expressionparser.operator.Operator;
import ch.andre601.expressionparser.parsers.ExpressionTemplateParser;
import ch.andre601.expressionparser.parsers.ValueReader;
import ch.andre601.expressionparser.templates.ExpressionTemplate;
import ch.andre601.expressionparser.tokens.Token;
import ch.andre601.expressionparser.tokens.readers.TokenReader;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.List;
public class ProfileConditionParser implements ExpressionParserEngine{
private final CustomExpressionTokenizer tokenizer;
private final ExpressionTemplateParser parser;
private ProfileConditionParser(List<TokenReader> tokenReaders, ImmutableMap<Token, Operator> operators, ImmutableList<ValueReader> valueReaders){
this.tokenizer = new CustomExpressionTokenizer(tokenReaders);
this.parser = new ExpressionTemplateParser(operators, valueReaders);
}
public static ProfileConditionParser create(){
return new ProfileConditionParserBuilder().createDefault()
.addTokenReader(new PlaceholderTokenReader(-20))
.addValueReader(new PlaceholderValueReader())
.build();
}
public ExpressionTemplate compile(String text, GenericPlayer player, GenericServer server, ParseWarnCollector collector){
return parser.parse(tokenizer.parse(text, player, server, collector), collector);
}
@Override
public ExpressionTemplate compile(String s, ParseWarnCollector parseWarnCollector){
return null;
}
private static class ProfileConditionParserBuilder extends ExpressionParserEngine.Builder<ProfileConditionParser>{
@Override
public ProfileConditionParser build(){
return new ProfileConditionParser(this.getTokenReaders(), ImmutableMap.copyOf(this.getOperators()), ImmutableList.copyOf(this.getValueReaders()));
}
}
}
@@ -1,28 +0,0 @@
/*
* 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{}
@@ -1,176 +0,0 @@
/*
* 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.STARTS_WITH, "|-"))
.tokenReader(new PatternTokenReader(DefaultTokens.ENDS_WITH, "-|"))
.tokenReader(new PatternTokenReader(DefaultTokens.CONTAINS, "<-"))
.tokenReader(new PatternTokenReader(DefaultTokens.GREATER_OR_EQUAL_THAN, ">="))
.tokenReader(new PatternTokenReader(DefaultTokens.LESSER_OR_EQUAL_THAN, "<="))
.tokenReader(new PatternTokenReader(DefaultTokens.OPENING_PARENTHESIS, "("))
.tokenReader(new PatternTokenReader(DefaultTokens.CLOSING_PARENTHESIS, ")"))
.tokenReader(new PatternTokenReader(DefaultTokens.NEGATION, "!"))
.tokenReader(new PatternTokenReader(DefaultTokens.GREATER_THAN, ">"))
.tokenReader(new PatternTokenReader(DefaultTokens.LESSER_THAN, "<"))
.tokenReader(new PatternTokenReader(DefaultTokens.CONCAT_STRING, "."))
.tokenReader(new PatternTokenReader(DefaultTokens.ADD, "+"))
.tokenReader(new PatternTokenReader(DefaultTokens.SUB, "-"))
.tokenReader(new PatternTokenReader(DefaultTokens.MULT, "*"))
.tokenReader(new PatternTokenReader(DefaultTokens.DIV, "/"))
.tokenReader(new QuotedLiteralTokenReader(-10, '\"'))
.tokenReader(new QuotedLiteralTokenReader(-10, '\''))
.tokenReader(new PlaceholderTokenReader(-20))
.tokenReader(new NumberTokenReader(-50))
.tokenReader(new NonQuotedLiteralTokenReader(-100));
}
public Builder withDefaultOperators(){
return this
.operator(DefaultTokens.AND, ListOperator.of(100, ExpressionTemplates::and))
.operator(DefaultTokens.OR, ListOperator.of(50, ExpressionTemplates::or))
.operator(DefaultTokens.EQUAL, Operator.of(25, ExpressionTemplates::equal))
.operator(DefaultTokens.NOT_EQUAL, Operator.of(25, ExpressionTemplates::notEqual))
.operator(DefaultTokens.EQUAL_IGNORE_CASE, Operator.of(25, ExpressionTemplates::equalIgnoreCase))
.operator(DefaultTokens.NOT_EQUAL_IGNORE_CASE, Operator.of(25, ExpressionTemplates::notEqualIgnoreCase))
.operator(DefaultTokens.STARTS_WITH, Operator.of(25, ExpressionTemplates::startsWith))
.operator(DefaultTokens.ENDS_WITH, Operator.of(25, ExpressionTemplates::endsWith))
.operator(DefaultTokens.CONTAINS, Operator.of(25, ExpressionTemplates::contains))
.operator(DefaultTokens.GREATER_THAN, Operator.of(25, ExpressionTemplates::greater))
.operator(DefaultTokens.GREATER_OR_EQUAL_THAN, Operator.of(25, ExpressionTemplates::greaterOrEqual))
.operator(DefaultTokens.LESSER_THAN, Operator.of(25, ExpressionTemplates::less))
.operator(DefaultTokens.LESSER_OR_EQUAL_THAN, Operator.of(25, ExpressionTemplates::lessOrEqual))
.operator(DefaultTokens.CONCAT_STRING, ListOperator.of(10, ExpressionTemplates::concat))
.operator(DefaultTokens.ADD, ListOperator.of(4, ExpressionTemplates::sum))
.operator(DefaultTokens.SUB, Operator.of(3, ExpressionTemplates::sub))
.operator(DefaultTokens.MULT, ListOperator.of(2, ExpressionTemplates::product))
.operator(DefaultTokens.DIV, Operator.of(1, ExpressionTemplates::div));
}
public Builder withDefaultValueReaders(){
return this
.valueReader(new BooleanConstantReader())
.valueReader(new NumberConstantReader())
.valueReader(new StringConstantReader())
.valueReader(new NegatedExpressionReader(DefaultTokens.NEGATION))
.valueReader(new ParenthesisedExpressionReader(DefaultTokens.OPENING_PARENTHESIS, DefaultTokens.CLOSING_PARENTHESIS))
.valueReader(new PlaceholderReader())
.valueReader(new NegatedNumberReader(DefaultTokens.SUB));
}
public Builder tokenReader(TokenReader tokenReader){
this.tokenReaders.add(tokenReader);
return this;
}
public Builder operator(Token token, Operator operator){
this.operators.put(token, operator);
return this;
}
public Builder valueReader(ValueReader valueReader){
this.valueReaders.add(valueReader);
return this;
}
public Options build(){
return new Options(this.tokenReaders, ImmutableMap.copyOf(operators), ImmutableList.copyOf(valueReaders));
}
}
}
}
@@ -1,238 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.*;
import java.util.Collection;
public class Expressions{
public static ToBooleanExpression negate(ToBooleanExpression expression){
return new AbstractUnaryToBooleanExpression<>(expression){
@Override
public boolean evaluate(){
return !delegate.evaluate();
}
};
}
public static ToBooleanExpression and(Collection<ToBooleanExpression> operands){
return new AbstractToBooleanExpression<>(operands){
@Override
public boolean evaluate(){
for(ToBooleanExpression operand : operands){
if(!operand.evaluate())
return false;
}
return true;
}
};
}
public static ToBooleanExpression or(Collection<ToBooleanExpression> operands){
return new AbstractToBooleanExpression<>(operands){
@Override
public boolean evaluate(){
for(ToBooleanExpression operand : operands){
if(operand.evaluate())
return true;
}
return false;
}
};
}
public static ToStringExpression concat(Collection<ToStringExpression> operands){
return new AbstractToStringExpression<>(operands){
@Override
public String evaluate(){
StringBuilder result = new StringBuilder();
for(ToStringExpression operand : operands){
result.append(operand.evaluate());
}
return result.toString();
}
};
}
public static ToBooleanExpression equal(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate().equals(b.evaluate());
}
};
}
public static ToBooleanExpression notEqual(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return !a.evaluate().equals(b.evaluate());
}
};
}
public static ToBooleanExpression equalIgnoreCase(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate().equalsIgnoreCase(b.evaluate());
}
};
}
public static ToBooleanExpression notEqualIgnoreCase(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return !a.evaluate().equalsIgnoreCase(b.evaluate());
}
};
}
public static ToBooleanExpression startsWith(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate().startsWith(b.evaluate());
}
};
}
public static ToBooleanExpression endsWith(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate().endsWith(b.evaluate());
}
};
}
public static ToBooleanExpression contains(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate().contains(b.evaluate());
}
};
}
public static ToBooleanExpression greaterThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate() > b.evaluate();
}
};
}
public static ToBooleanExpression greaterOrEqualThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate() >= b.evaluate();
}
};
}
public static ToBooleanExpression lessThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate() < b.evaluate();
}
};
}
public static ToBooleanExpression lessOrEqualThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate() <= b.evaluate();
}
};
}
public static ToDoubleExpression sum(Collection<ToDoubleExpression> operands){
return new AbstractToDoubleExpression<>(operands){
@Override
public double evaluate(){
double result = 0;
for(ToDoubleExpression operand : operands){
result += operand.evaluate();
}
return result;
}
};
}
public static ToDoubleExpression product(Collection<ToDoubleExpression> operands){
return new AbstractToDoubleExpression<>(operands){
@Override
public double evaluate(){
double result = 1;
for(ToDoubleExpression operand : operands){
result *= operand.evaluate();
}
return result;
}
};
}
public static ToDoubleExpression sub(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToDoubleExpression<>(a, b){
@Override
public double evaluate(){
return a.evaluate() - b.evaluate();
}
};
}
public static ToDoubleExpression div(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToDoubleExpression<>(a, b){
@Override
public double evaluate(){
return a.evaluate() / b.evaluate();
}
};
}
public static ToDoubleExpression negateNumber(ToDoubleExpression a){
return new AbstractUnaryToDoubleExpression<>(a){
@Override
public double evaluate(){
return -delegate.evaluate();
}
};
}
}
@@ -1,49 +0,0 @@
/*
* 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;
}
}
}
@@ -1,56 +0,0 @@
/*
* 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);
}
@@ -1,44 +0,0 @@
/*
* 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;
}
}
@@ -1,133 +0,0 @@
/*
* 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() + "\"");
}
}
@@ -1,51 +0,0 @@
/*
* 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;
}
}
@@ -1,51 +0,0 @@
/*
* 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;
}
}
@@ -1,43 +0,0 @@
/*
* 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;
}
}
@@ -1,71 +0,0 @@
/*
* 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;
}
}
@@ -1,44 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ConstantExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.StringToken;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import java.util.List;
public class StringConstantReader extends ValueReader{
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) instanceof StringToken){
return ConstantExpressionTemplate.of(((StringToken)tokenList.remove(0)).getValue());
}
return null;
}
}
@@ -1,36 +0,0 @@
/*
* 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);
}
@@ -1,62 +0,0 @@
/*
* 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));
}
}
}
@@ -29,13 +29,19 @@ 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 ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.tokens.PlaceholderToken;
import ch.andre601.expressionparser.ParseWarnCollector;
import java.text.ParsePosition;
public class PlaceholderParser{
public static Placeholder parse(String text, ParsePosition position, GenericPlayer player, GenericServer server){
public static PlaceholderToken.Placeholder parse(String text, ParsePosition position, GenericPlayer player, GenericServer server, ParseWarnCollector collector){
AdvancedServerListAPI api = AdvancedServerListAPI.get();
// We want to point to the start of a placeholder in the ParseWarnCollector.
// Since the PlaceholderTokenReader updates the index by 2 are we reverting this here.
int placeholderStart = position.getIndex() - 2;
int index = position.getIndex();
StringBuilder identifier = new StringBuilder();
@@ -47,6 +53,7 @@ public class PlaceholderParser{
char[] chars = text.substring(index).toCharArray();
for(final char c : chars){
index++;
if(c == '}'){
invalid = false;
break;
@@ -69,6 +76,7 @@ public class PlaceholderParser{
StringBuilder raw = new StringBuilder();
// Skipping whatever character we currently were on (i.e. })
position.setIndex(index + 1);
if(invalid){
@@ -77,8 +85,8 @@ public class PlaceholderParser{
if(identified)
raw.append(' ').append(valuesStr);
return Placeholder.of(raw.toString());
collector.appendWarningFormatted(placeholderStart, "Placeholder '%s' does not have a closing bracket (}).", raw.toString());
return new PlaceholderToken.Placeholder(raw.toString());
}
PlaceholderProvider provider = api.retrievePlaceholderProvider(identifierStr);
@@ -88,10 +96,10 @@ public class PlaceholderParser{
if(identified)
raw.append(' ').append(valuesStr);
raw.append('}');
return Placeholder.of(raw.toString());
collector.appendWarningFormatted(placeholderStart, "Placeholder '%s' does not have any available PlaceholderProvider", raw.toString());
return new PlaceholderToken.Placeholder(raw.toString());
}
String replacement = provider.parsePlaceholder(valuesStr, player, server);
@@ -103,9 +111,10 @@ public class PlaceholderParser{
raw.append('}');
return Placeholder.of(raw.toString());
collector.appendWarningFormatted(placeholderStart, "Placeholder '%s' has an invalid value String '%s'.", raw.toString(), valuesStr);
return new PlaceholderToken.Placeholder(raw.toString());
}
return Placeholder.of(replacement);
return new PlaceholderToken.Placeholder(replacement);
}
}
@@ -23,25 +23,26 @@
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
package ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.reader;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
import ch.andre601.expressionparser.ParseWarnCollector;
import ch.andre601.expressionparser.tokens.Token;
import ch.andre601.expressionparser.tokens.readers.TokenReader;
import java.text.ParsePosition;
public abstract class TokenReader{
public abstract class CustomTokenReader extends TokenReader{
private final int priority;
public TokenReader(int priority){
this.priority = priority;
public CustomTokenReader(int priority){
super(priority);
}
public int getPriority(){
return priority;
@Override
public Token read(String text, ParsePosition position, ParseWarnCollector collector){
return null;
}
public abstract Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server);
public abstract Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server, ParseWarnCollector collector);
}
@@ -23,27 +23,28 @@
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
package ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.reader;
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 ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.tokens.PlaceholderToken;
import ch.andre601.expressionparser.ParseWarnCollector;
import ch.andre601.expressionparser.tokens.Token;
import java.text.ParsePosition;
public class PlaceholderTokenReader extends TokenReader{
public class PlaceholderTokenReader extends CustomTokenReader{
public PlaceholderTokenReader(int priority){
super(priority);
}
@Override
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server, ParseWarnCollector collector){
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 new PlaceholderToken(PlaceholderParser.parse(text, position, player, server, collector));
}
return null;
}
@@ -23,19 +23,22 @@
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
package ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.reader;
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 ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.tokens.PlaceholderToken;
import ch.andre601.expressionparser.ParseWarnCollector;
import ch.andre601.expressionparser.parsers.ExpressionTemplateParser;
import ch.andre601.expressionparser.parsers.ValueReader;
import ch.andre601.expressionparser.templates.ExpressionTemplate;
import ch.andre601.expressionparser.tokens.Token;
import java.util.List;
public class PlaceholderReader extends ValueReader{
public class PlaceholderValueReader extends ValueReader{
@Override
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
if(tokenList.get(0) instanceof PlaceholderToken){
PlaceholderToken token = (PlaceholderToken)tokenList.remove(0);
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokens, ParseWarnCollector collector){
if(tokens.get(0) instanceof PlaceholderToken){
PlaceholderToken token = (PlaceholderToken)tokens.remove(0);
return token.getValue();
}
return null;
@@ -23,13 +23,14 @@
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions;
package ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.tokens;
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 ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.reader.CustomTokenReader;
import ch.andre601.expressionparser.ParseWarnCollector;
import ch.andre601.expressionparser.tokens.Token;
import ch.andre601.expressionparser.tokens.readers.TokenReader;
import com.google.common.collect.Ordering;
import java.text.ParsePosition;
@@ -37,39 +38,45 @@ import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class ExpressionTokenizer{
public class CustomExpressionTokenizer{
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){
public CustomExpressionTokenizer(Iterable<TokenReader> tokenReaders){
this.tokenReaders = TOKEN_READER_ORDERING.immutableSortedCopy(tokenReaders);
}
public List<Token> parse(String text, PluginLogger logger, GenericPlayer player, GenericServer server){
public List<Token> parse(String text, GenericPlayer player, GenericServer server, ParseWarnCollector collector){
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()))){
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;
if(tokenReader instanceof CustomTokenReader customTokenReader){
if(null != (token = customTokenReader.read(text, position, player, server, collector))){
tokens.add(token);
continue next_token;
}
}else{
if(null != (token = tokenReader.read(text, position, collector))){
tokens.add(token);
continue next_token;
}
}
}
logger.warn("Illegal token '%c' at index %d.", text.charAt(position.getIndex()), position.getIndex());
collector.appendWarningFormatted(position.getIndex(), "Illegal Token '%c'.", text.charAt(position.getIndex()));
break;
}
@@ -0,0 +1,81 @@
/*
* 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.tokens;
import ch.andre601.expressionparser.expressions.ToBooleanExpression;
import ch.andre601.expressionparser.expressions.ToDoubleExpression;
import ch.andre601.expressionparser.expressions.ToStringExpression;
import ch.andre601.expressionparser.templates.ExpressionTemplate;
import ch.andre601.expressionparser.tokens.Token;
public class PlaceholderToken extends Token{
private final Placeholder value;
public PlaceholderToken(Placeholder value){
super("PLACEHOLDER");
this.value = value;
}
public Placeholder getValue(){
return value;
}
public static class Placeholder implements ExpressionTemplate{
private final ToBooleanExpression toBooleanExpression;
private final ToDoubleExpression toDoubleExpression;
private final ToStringExpression toStringExpression;
public Placeholder(String value){
double doubleValue;
try{
doubleValue = Double.parseDouble(value);
}catch(NumberFormatException ex){
doubleValue = value.length();
}
this.toBooleanExpression = ToBooleanExpression.literal(Boolean.parseBoolean(value));
this.toDoubleExpression = ToDoubleExpression.literal(doubleValue);
this.toStringExpression = ToStringExpression.literal(value);
}
@Override
public ToBooleanExpression returnBooleanExpression(){
return toBooleanExpression;
}
@Override
public ToDoubleExpression returnDoubleExpression(){
return toDoubleExpression;
}
@Override
public ToStringExpression returnStringExpression(){
return toStringExpression;
}
}
}
@@ -1,40 +0,0 @@
/*
* 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;
}
}
@@ -1,40 +0,0 @@
/*
* 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;
}
}
@@ -1,43 +0,0 @@
/*
* 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());
}
}
@@ -1,43 +0,0 @@
/*
* 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());
}
}
@@ -1,43 +0,0 @@
/*
* 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());
}
}
@@ -1,40 +0,0 @@
/*
* 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;
}
}
@@ -1,40 +0,0 @@
/*
* 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;
}
}
@@ -1,40 +0,0 @@
/*
* 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;
}
}
@@ -1,38 +0,0 @@
/*
* 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;
}
}
@@ -1,38 +0,0 @@
/*
* 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;
}
}
@@ -1,38 +0,0 @@
/*
* 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;
}
}
@@ -1,77 +0,0 @@
/*
* 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;
}
}
@@ -1,58 +0,0 @@
/*
* 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);
}
}
@@ -1,39 +0,0 @@
/*
* 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();
}
@@ -1,422 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expressions;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
import java.util.Collection;
public class ExpressionTemplates{
public static ExpressionTemplate negate(ExpressionTemplate template){
return new Negation(template);
}
public static ExpressionTemplate and(Collection<ExpressionTemplate> operands){
return new And(operands);
}
public static ExpressionTemplate or(Collection<ExpressionTemplate> operands){
return new Or(operands);
}
public static ExpressionTemplate concat(Collection<ExpressionTemplate> operands){
return new Concatenate(operands);
}
public static ExpressionTemplate equal(ExpressionTemplate a, ExpressionTemplate b){
return new Equal(a, b);
}
public static ExpressionTemplate notEqual(ExpressionTemplate a, ExpressionTemplate b){
return new NotEqual(a, b);
}
public static ExpressionTemplate equalIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
return new EqualIgnoreCase(a, b);
}
public static ExpressionTemplate notEqualIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
return new NotEqualIgnoreCase(a, b);
}
public static ExpressionTemplate startsWith(ExpressionTemplate a, ExpressionTemplate b){
return new StartsWith(a, b);
}
public static ExpressionTemplate endsWith(ExpressionTemplate a, ExpressionTemplate b){
return new EndsWith(a, b);
}
public static ExpressionTemplate contains(ExpressionTemplate a, ExpressionTemplate b){
return new Contains(a, b);
}
public static ExpressionTemplate greater(ExpressionTemplate a, ExpressionTemplate b){
return new Greater(a, b);
}
public static ExpressionTemplate greaterOrEqual(ExpressionTemplate a, ExpressionTemplate b){
return new GreaterOrEqual(a, b);
}
public static ExpressionTemplate less(ExpressionTemplate a, ExpressionTemplate b){
return new Less(a, b);
}
public static ExpressionTemplate lessOrEqual(ExpressionTemplate a, ExpressionTemplate b){
return new LessOrEqual(a, b);
}
public static ExpressionTemplate sum(Collection<ExpressionTemplate> operands){
return new Sum(operands);
}
public static ExpressionTemplate product(Collection<ExpressionTemplate> operands){
return new Product(operands);
}
public static ExpressionTemplate sub(ExpressionTemplate a, ExpressionTemplate b){
return new Sub(a, b);
}
public static ExpressionTemplate div(ExpressionTemplate a, ExpressionTemplate b){
return new Div(a, b);
}
public static ExpressionTemplate negateNumber(ExpressionTemplate template){
return new NegationNumber(template);
}
private static class Negation extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate template;
Negation(ExpressionTemplate template){
this.template = template;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.negate(template.instantiateWithBooleanResult());
}
}
private static class And extends AbstractBooleanExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
And(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.and(operands.stream().map(ExpressionTemplate::instantiateWithBooleanResult).toList());
}
}
private static class Or extends AbstractBooleanExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
Or(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.or(operands.stream().map(ExpressionTemplate::instantiateWithBooleanResult).toList());
}
}
private static class Concatenate extends AbstractStringExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
Concatenate(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToStringExpression instantiateWithStringResult(){
return Expressions.concat(operands.stream().map(ExpressionTemplate::instantiateWithStringResult).toList());
}
}
private static class Equal extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Equal(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.equal(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class NotEqual extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
NotEqual(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.notEqual(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class EqualIgnoreCase extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
EqualIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.equalIgnoreCase(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class NotEqualIgnoreCase extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
NotEqualIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.notEqualIgnoreCase(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class StartsWith extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
private StartsWith(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.startsWith(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class EndsWith extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
private EndsWith(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.endsWith(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class Contains extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
private Contains(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.contains(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class Greater extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Greater(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.greaterThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class GreaterOrEqual extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
GreaterOrEqual(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.greaterOrEqualThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class Less extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Less(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.lessThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class LessOrEqual extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
LessOrEqual(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.lessOrEqualThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class Sum extends AbstractDoubleExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
Sum(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.sum(operands.stream().map(ExpressionTemplate::instantiateWithDoubleResult).toList());
}
}
private static class Product extends AbstractDoubleExpressionTemplate{
private final Collection<ExpressionTemplate> operands;
Product(Collection<ExpressionTemplate> operands){
this.operands = operands;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.product(operands.stream().map(ExpressionTemplate::instantiateWithDoubleResult).toList());
}
}
private static class Sub extends AbstractDoubleExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Sub(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.sub(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class Div extends AbstractDoubleExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
Div(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.div(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
}
}
private static class NegationNumber extends AbstractDoubleExpressionTemplate{
private final ExpressionTemplate template;
NegationNumber(ExpressionTemplate template){
this.template = template;
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return Expressions.negateNumber(template.instantiateWithDoubleResult());
}
}
}
@@ -1,42 +0,0 @@
/*
* 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;
}
}
@@ -1,50 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens;
public class DefaultTokens{
public static final Token AND = new Token("AND");
public static final Token OR = new Token("OR");
public static final Token OPENING_PARENTHESIS = new Token("OPENING_PARENTHESIS");
public static final Token CLOSING_PARENTHESIS = new Token("CLOSING_PARENTHESIS");
public static final Token EQUAL = new Token("EQUAL");
public static final Token NOT_EQUAL = new Token("NOT_EQUAL");
public static final Token EQUAL_IGNORE_CASE = new Token("EQUAL_IGNORE_CASE");
public static final Token NOT_EQUAL_IGNORE_CASE = new Token("NOT_EQUAL_IGNORE_CASE");
public static final Token STARTS_WITH = new Token("STARTS_WITH");
public static final Token ENDS_WITH = new Token("ENDS_WITH");
public static final Token CONTAINS = new Token("CONTAINS");
public static final Token NEGATION = new Token("NEGATION");
public static final Token GREATER_THAN = new Token("GREATER_THAN");
public static final Token GREATER_OR_EQUAL_THAN = new Token("GREATER_OR_EQUAL_THAN");
public static final Token LESSER_THAN = new Token("LESSER_THAN");
public static final Token LESSER_OR_EQUAL_THAN = new Token("LESSER_OR_EQUAL_THAN");
public static final Token CONCAT_STRING = new Token("CONCAT_STRING");
public static final Token ADD = new Token("ADD");
public static final Token SUB = new Token("SUB");
public static final Token MULT = new Token("MULT");
public static final Token DIV = new Token("DIV");
}
@@ -1,40 +0,0 @@
/*
* 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;
}
}
@@ -1,42 +0,0 @@
/*
* 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;
}
}
@@ -1,40 +0,0 @@
/*
* 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;
}
}
@@ -1,53 +0,0 @@
/*
* 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()));
}
}
@@ -1,55 +0,0 @@
/*
* 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;
}
}
@@ -1,61 +0,0 @@
/*
* 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;
}
}
@@ -1,62 +0,0 @@
/*
* 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;
}
}
@@ -26,145 +26,167 @@
package ch.andre601.advancedserverlist.core.profiles.favicon;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.*;
import java.util.function.Function;
import java.util.stream.Stream;
public class FaviconHandler<F>{
private final Cache<String, CompletableFuture<F>> favicons = CacheBuilder.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.build();
private final AdvancedServerList<F> core;
private final PluginLogger logger;
private final ThreadPoolExecutor faviconThreadPool;
private final Cache<String, CompletableFuture<F>> faviconCache;
private final Map<String, F> localFavicons = new HashMap<>();
private final HttpClient client = HttpClient.newHttpClient();
public FaviconHandler(AdvancedServerList<F> core){
this.core = core;
this.logger = core.getPlugin().getPluginLogger();
this.faviconThreadPool = createFaviconThreadPool();
this.faviconCache = CacheBuilder.newBuilder()
.expireAfterWrite(core.getFileHandler().getLong(1, 1, "faviconCacheTime"), TimeUnit.MINUTES)
.build();
loadLocalFavicons();
}
public F getFavicon(String input, Function<BufferedImage, F> function){
public F getFavicon(String input){
if(localFavicons.containsKey(input.toLowerCase(Locale.ROOT).split("\\.")[0])){
return localFavicons.get(input.toLowerCase(Locale.ROOT).split("\\.")[0]);
}
try{
return favicons.get(input, () -> convert(input, function)).getNow(null);
}catch(ExecutionException e){
return faviconCache.get(input, () -> getFuture(input)).getNow(null);
}catch(ExecutionException ex){
logger.warn("Received ExecutionException while retrieving Favicon for '%s'.", ex, input);
return null;
}
}
public void clearCache(){
favicons.invalidateAll();
public void cleanCache(){
faviconCache.invalidateAll();
loadLocalFavicons();
}
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){
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;
private CompletableFuture<F> getFuture(String input){
if(input.toLowerCase(Locale.ROOT).startsWith("https://")){
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "URL detected. Getting file from it...");
stream = getFromUrl(core, input);
logger.debug(FaviconHandler.class, "Resolving URL '%s'...", input);
return CompletableFuture.supplyAsync(() -> fromURL(core, input), this.faviconThreadPool);
}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);
return null;
}
File file = new File(folder, input);
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;
}
logger.debug(FaviconHandler.class, "Resolving image file '%s'...", input);
return CompletableFuture.completedFuture(localFavicons.get(input.toLowerCase(Locale.ROOT).split("\\.")[0]));
}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");
logger.debug(FaviconHandler.class, "Resolving Name/UUID as https://mc-heads.net/avatar/%s/64...", input);
return CompletableFuture.supplyAsync(() -> fromURL(core, "https://mc-heads.net/avatar/" + input + "/64"), this.faviconThreadPool);
}
}
private void loadLocalFavicons(){
this.localFavicons.clear();
logger.info("Loading local image files as Favicons...");
Path folder = core.getPlugin().getFolderPath().resolve("favicons");
if(!Files.exists(folder)){
try{
Files.createDirectories(folder);
logger.info("Created favicons folder.");
}catch(IOException ex){
logger.warn("Cannot create favicons folder. Encountered an IOException.", ex);
return;
}
}
if(stream == null){
core.getPlugin().getPluginLogger().warn("Cannot create Favicon. InputStream was null.");
return null;
try(Stream<Path> pathStream = Files.list(folder)){
pathStream.filter(Files::isRegularFile)
.filter(file -> file.getFileName().toString().endsWith(".png"))
.forEach(this::loadFile);
}catch(IOException ex){
logger.warn("Cannot load files from Favicons folder.", ex);
}
try{
BufferedImage original = ImageIO.read(stream);
if(original == null){
core.getPlugin().getPluginLogger().warn("Cannot create Favicon. Unable to create BufferedImage.");
return null;
}
private void loadFile(Path path){
try(InputStream stream = Files.newInputStream(path)){
F favicon = createFavicon(stream);
if(favicon == null){
logger.warn("Cannot create Favicon from file '%s'. Received Favicon was null.", path.getFileName().toString());
return;
}
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();
// Resize original image to 64x64 and apply to favicon.
img.drawImage(original, 0, 0, 64, 64, null);
img.dispose();
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Image resized!");
return favicon;
localFavicons.put(path.getFileName().toString().split("\\.")[0], favicon);
logger.info("Loaded file '%s' as Favicon.", path.getFileName().toString());
}catch(IOException ex){
core.getPlugin().getPluginLogger().warn("Unable to create Favicon. Encountered IOException during creation.");
core.getPlugin().getPluginLogger().warn("Cause: %s", ex.getMessage());
logger.warn("Cannot create Favicon from file '%s'. Encountered IOException.", ex);
}
}
private F fromURL(AdvancedServerList<F> core, String url){
try{
logger.debug(FaviconHandler.class, "Creating Request for URL '%s'...", url);
HttpRequest request = HttpRequest.newBuilder()
.uri(new URI(url))
.header("User-Agent", "AdvancedServerList-" + core.getPlugin().getLoader() + "/" + core.getVersion())
.build();
try(InputStream stream = client.send(request, HttpResponse.BodyHandlers.ofInputStream()).body()){
return createFavicon(stream);
}catch(InterruptedException | IOException ex){
logger.warn("Cannot create Favicon from URL '%s'. Encountered an Exception.", ex, url);
return null;
}
}catch(URISyntaxException ex){
logger.warn("Cannot create Favicon from URL '%s'. Encountered an IOException.", ex, url);
return null;
}
}
private InputStream getFromUrl(AdvancedServerList<F> core, String url){
private F createFavicon(InputStream stream){
try{
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resolving URL '%s'...", url);
logger.debug(FaviconHandler.class, "Creating BufferedImage from InputStream...");
BufferedImage original = ImageIO.read(stream);
if(original == null){
logger.warn("Cannot create Favicon. Received null BufferedImage.");
return null;
}
URL faviconUrl = new URL(url);
URLConnection connection = faviconUrl.openConnection();
connection.setRequestProperty("User-Agent", "AdvancedServerList/" + core.getVersion());
connection.connect();
// Don't waste resources resizing images already having right size.
if(original.getWidth() == 64 && original.getHeight() == 64){
logger.debug(FaviconHandler.class, "BufferedImage is 64x64 pixels. No resizing needed.");
return core.getPlugin().createFavicon(original);
}
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);
core.getPlugin().getPluginLogger().warn("Cause: %s", ex.getMessage());
logger.debug(FaviconHandler.class, "Resizing image to 64x64 pixels...");
BufferedImage image = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics2D = image.createGraphics();
graphics2D.drawImage(original, 0, 0, 64, 64, null);
graphics2D.dispose();
logger.debug(FaviconHandler.class, "Image resized! Returning Favicon...");
return core.getPlugin().createFavicon(image);
}catch(Exception ex){
logger.warn("Unable to create Favicon. Received Exception.", ex);
return null;
}
}
@@ -38,7 +38,9 @@ import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class PlayerHandler{
@@ -28,9 +28,9 @@ package ch.andre601.advancedserverlist.core.profiles.profile;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.api.objects.NullBool;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
@@ -45,7 +45,7 @@ public class ProfileManager{
*/
public static ProfileEntry merge(ServerListProfile profile){
ProfileEntry entry = profile.getRandomProfile();
ProfileEntry defEntry = profile.getDefaultProfile();
ProfileEntry defEntry = profile.defaultProfile();
List<String> motd = resolveMOTD(entry, defEntry);
List<String> players = resolvePlayers(entry, defEntry);
@@ -67,7 +67,7 @@ public class ProfileManager{
if(profile.isInvalidProfile())
continue;
if(profile.evalConditions(core.getExpressionEngine(), core.getPlugin().getPluginLogger(), player, server))
if(profile.evalConditions(core.getParser(), core.getPlugin().getPluginLogger(), player, server))
return profile;
}
@@ -25,11 +25,11 @@
package ch.andre601.advancedserverlist.core.profiles.profile;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.serialize.TypeSerializer;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import java.lang.reflect.Type;
+8
View File
@@ -42,6 +42,14 @@ checkUpdates: true
#
debug: false
#
# Sets the time in minutes for favicons to be cached.
# The number cannot be less than 1.
#
# Defaults to 1 if not set.
#
faviconCacheTime: 1
#
# DO NOT EDIT!
#
@@ -25,7 +25,9 @@
package ch.andre601.advancedserverlist.test;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionEngine;
import ch.andre601.advancedserverlist.core.profiles.conditions.ProfileConditionParser;
import ch.andre601.expressionparser.ParseWarnCollector;
import ch.andre601.expressionparser.templates.ExpressionTemplate;
import org.junit.jupiter.api.Test;
import java.util.Map;
@@ -34,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
public class ExpressionParserTests{
private final ExpressionEngine expressionEngine = new ExpressionEngine();
private final ProfileConditionParser parser = ProfileConditionParser.create();
private final DummyPluginLogger logger = new DummyPluginLogger();
private final Map<String, Boolean> testValuesMap = getTestMap();
@@ -43,7 +45,15 @@ public class ExpressionParserTests{
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();
ParseWarnCollector collector = new ParseWarnCollector(values.getKey());
ExpressionTemplate template = parser.compile(values.getKey(), null, null, collector);
boolean result;
if(template == null){
result = false;
}else{
result = template.returnBooleanExpression().evaluate();
}
logger.info("Result (output, isExpected): " + result + ", " + (result == values.getValue()));
assertEquals(result, values.getValue());
}
-4
View File
@@ -9,7 +9,6 @@
from __future__ import annotations
import posixpath
import re
from mkdocs.config.defaults import MkDocsConfig
@@ -39,9 +38,6 @@ def on_page_markdown(
elif type == "deprecated": return _admo(text = args, type = "deprecated")
else: return _admo(text = args)
# Otherwise, raise an error
raise RuntimeError(f"Unknown shortcode: {type}")
# Find and replace all external asset URLs in current page
return re.sub(
r"<!-- admo:(\w+)(.*?) -->",
+26
View File
@@ -0,0 +1,26 @@
#
# A simple hook that replaces any appearances of \| with just |.
#
# There is an inconsistency between GitHub flavourited Markdown and Python Markdown
# where the former treats | as part of a table, even if it is inside inline code
# causing unwanted table rendering.
#
# The only way to prevent this is to escape it by prefixing it with a back slash (\).
# Unfortunately does this cause issues on Python-Markdown, as it renders inline code
# content as-is without special treatments whatsoever, meaning that `\|` will be
# rendered as <code>\|</code> in the end.
#
# Using this hook, `\|` is being turned into `|` before further processing, resulting
# in <code>|</code> being rendered in the end, while preserving proper table rendering
# on GitHub and co.
#
import re
from mkdocs.config.defaults import MkDocsConfig
from mkdocs.structure.files import File, Files
from mkdocs.structure.pages import Page
def on_page_markdown(
markdown: str, *, page: Page, config: MkDocsConfig, files: Files
):
return re.sub(r"\\\|","|",markdown)
+2 -1
View File
@@ -6,4 +6,5 @@ nav:
- examples
- migration
- api
- PlaceholderAPI: placeholderapi
- addons
- PlaceholderAPI: placeholderapi
+44
View File
@@ -0,0 +1,44 @@
# BanPlugins Addon
The BanPlugins Addon was made to provide placeholders for different punishment plugins to use in AdvancedServerList.
## Placeholders
### AdvancedBan
Placeholders for the plugin [AdvancedBan](https://www.spigotmc.org/resources/8695/){ target="_blank" rel="nofollow" } are available to use.
| Placeholder | Description |
|---------------------------------|-------------------------------------------------------------------------------------------|
| `${advancedban isMuted}` | Whether the player is muted or not. |
| `${advancedban muteReason}` | The reason for why the player was muted. Returns invalid placeholder if no mute was set. |
| `${advancedban muteDuration}` | Relative time until the mute expires.[^1] Returns invalid placeholder if no mute was set. |
| `${advancedban muteExpiration}` | Date on when the mute will expire.[^2] |
| `${advancedban isBanned}` | Whether the player is banned or not. |
| `${advancedban banReason}` | The reason for why the player was banned. Returns invalid placeholder if no ban was set. |
| `${advancedban banDuration}` | Relative time until the ban expires.[^3] Returns invalid placeholder if no ban was set. |
| `${advancedban banExpiration}` | Date on when the ban will expire.[^4] |
[^1]:
An optional boolean can be added to set whether the duration should be from the start or not. `false` is the default.
Example: `${advancedban muteDuration true}`
[^2]:
An optional Date and time Pattern can be set to change the displayed output. The default is `dd, MMM yyyy HH:mm:ss`.
Example: `${advancedban muteExpiration yyyy-MM-dd HH:mm:ss}`
[^3]:
An optional boolean can be added to set whether the duration should be from the start or not. `false` is the default.
Example: `${advancedban banDuration true}`
[^4]:
An optional Date and time Pattern can be set to change the displayed output. The default is `dd, MMM yyyy HH:mm:ss`.
Example: `${advancedban banExpiration yyyy-MM-dd HH:mm:ss}`
## Example
```yaml title="banned.yml"
priority: 1
condition: '${advancedban isBanned}'
motd:
- '<red>You were <bold>BANNED</bold>!'
- '<red>Expires: <grey>${advancedban banExpiration}'
```
+28
View File
@@ -0,0 +1,28 @@
---
icon: octicons/plus-circle-24
---
# Addons
This section contains a curated list of add-ons for AdvancedServerList which can be used to enhance the plugin in different ways.
Do you have a plugin that hooks into AdvancedServerList that is not listed here? Contact Andre601 on Discord and it will be added!
## First-party Addons
These Addons are made by Andre601 and available together with the plugin downloads.
<div class="grid cards" markdown>
- [**BanPlugins**](banplugins.md)
----
Addon for different Punishment plugins such as AdvancedBan, that add new placeholders to use in AdvancedServerList.
</div>
## Third-party
Third-party addons made by other people not working on AdvancedServerList.
*Currently no entries*
+1 -1
View File
@@ -40,7 +40,7 @@ document$.subscribe(async () => {
const versionToken = '{version}'
const entries = document.querySelectorAll('.md-content code');
for(const entry of entries) {
entry.innerHTML = entry.innerHTML.replace(new RegExp(versionToken, 'g'), version);
entry.innerHTML = entry.innerHTML.replace(new RegExp(versionToken, 'g'), version.substring(1));
}
}
+25 -4
View File
@@ -17,7 +17,9 @@ Feel free to suggest additional examples on my [Discord Server](https://discord.
- [Versions](#versions)
- [Different List for outdated Clients](#different-list-for-outdated-clients)
- [Different MOTD for < 1.16](#different-motd-for-116)
- [Spigot/PaperMC](#spigotpapermc)
- [BungeeCord/Velocity](#bungeecordvelocity)
- [Display MOTD for a set of subdomains](#display-motd-for-a-set-of-subdomains)
- [PaperMC](#papermc)
- [Different profile for banned Player](#different-profile-for-banned-player)
- [Other](#other)
- [Different profile for different host](#different-profile-for-different-host)
@@ -64,9 +66,28 @@ motd:
```
----
## Spigot/PaperMC
## BungeeCord/Velocity
Examples that can be used with the Spigot or PaperMC version.
Examples usable on the BungeeCord and Velocity version.
### Display MOTD for a set of subdomains
Displays the same MOTDs for the server when pinged on any sub-domain starting with `lobby` (i.e. `lobby-1.example.com`).
```yaml title="lobby-motd.yml"
priority: 1
condition: '${server host} |- "lobby"'
motd:
- '<green>Lobby Server'
- '<grey>Example Server'
```
----
## PaperMC
Examples that can be used with the PaperMC version.
### Different profile for banned Player
@@ -114,7 +135,7 @@ Display a different profile, if the player pinging the server is "known" by Adva
```yaml title="personalized.yml"
priority: 1
condition: '${player name} != Anonymous' # "Anonymous" would be the value from the "unknownPlayer > name" option.
condition: '${player name} != "Anonymous"' # "Anonymous" would be the value from the "unknownPlayer > name" option.
motd:
- '<grey>Hello there <aqua>${player name}</aqua>!'
+85 -27
View File
@@ -9,19 +9,40 @@ It tries to be an easy to understand as possible. But if you still have problems
## 1. Download the plugin { #download-the-plugin }
The first step would be to download the plugin from a download page of your choice. As of writing this is AdvancedServerList updated and available on these sites:
The first step would be to download the plugin from a download page of your choice.
AdvancedServerList is available on the following places (Please note the current status!):
- [Modrinth]
- [Codeberg]
<div class="grid cards" markdown>
- [:simple-modrinth: **Modrinth**][modrinth]
----
:octicons-check-24:{ style="color: var(--md-badge-fg--success);" } **Actively updated!**
- [:simple-codeberg: **Codeberg**][codeberg]
----
:octicons-check-24:{ style="color: var(--md-badge-fg--success);" } **Actively updated!**
- [:fontawesome-solid-paper-plane: **HangarMC**][hangar]
----
:octicons-check-24:{ style="color: var(--md-badge-fg--success);" } **Actively updated!**
- [:simple-spigotmc: **SpigotMC**][spigot]
----
:octicons-alert-24:{ style="color: var(--md-badge-fg--warning);" } **Discontinued!**
</div>
[modrinth]: https://modrinth.com/plugin/advancedserverlist
[codeberg]: https://codeberg.org/Andre601/AdvancedServerList
The plugin is also available on these platforms, but not actively updated there anymore:
- [Spigot] (Latest version: `3.3.0-b1`)
- [Hangar] (Latest version: `3.5.0`)
[spigot]: https://www.spigotmc.org/resources/102910/
[hangar]: https://hangar.papermc.io/Andre_601/AdvancedServerList
@@ -29,10 +50,44 @@ The plugin is available for Paper, BungeeCord, Waterfall and Velocity, and has b
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 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.
<div class="grid cards" markdown>
- [**PlaceholderAPI**][placeholderapi]
----
Supported on:
- :fontawesome-solid-paper-plane: Paper
- [**ViaVersion**][viaversion]
----
Supported on:
- :fontawesome-solid-paper-plane: Paper
- [**PAPIProxyBridge**][papiproxybridge]
----
Supported on:
- :simple-spigotmc: BungeeCord
- :fontawesome-solid-paper-plane: Velocity
- [**Maintenance**][maintenance]
----
Supported on:
- :fontawesome-solid-paper-plane: Paper
- :simple-spigotmc: BungeeCord
- :fontawesome-solid-paper-plane: Velocity
</div>
[placeholderapi]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
[viaversion]: https://hangar.papermc.io/ViaVersion/ViaVersion
@@ -85,13 +140,12 @@ On first creation will the folder have a `default.yml` file. This file contains
priority: 0
#
# 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).
# 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/#conditions
# Read more: https://asl.andre601.ch/profiles/#condition
#
#conditions:
# - '{playerVersion} < 759'
# condition: '${player protocol} < 759'
#
# Option that allows you to define multiple profiles to use.
@@ -322,17 +376,17 @@ config-version: 2
There are certain files and folders that get created when certain events happen:
- A `playercache.json` file will be created on plugin shutdown containing a list of IPs, UUIDs and Player names for every player that joined the server while AdvancedServerList was running.
This file allows to replace `${player name}` and `${player uuid}` with their name or UUID respectively, while they are not on the server, by using the IP they used to join with.
This file is not created nor updated when `disableCache` is set to `true` in the config.yml
This file allows to replace `${player name}` and `${player uuid}` with their name or UUID respectively, while they are not on the server, by using the IP they used to join with.
This file is not created nor updated when `disableCache` is set to `true` in the config.yml
- A `backups` folder containing old config.yml files.
This folder is created when AdvancedServerList migrates your old config to a new version. This allows you to transfer settings over in case the migration didn't work properly.
This folder is created when AdvancedServerList migrates your old config to a new version. This allows you to transfer settings over in case the migration didn't work properly.
## 3. Creating your first profile { #creating-your-first-profile }
Creating your first profile is relatively simple.
To start, open the `default.yml` file located inside the `profiles` folder using a file editor of your choice (VSCode or Notepad++ are recommended). It should contain all the available options for a server list profile.
Next can you edit the options available to whatever you like. All text options (Except [conditions](../profiles/index.md#conditions)) support [MiniMessage formatting](../profiles/formatting.md).
Next can you edit the options available to whatever you like. All text options (Except [condition](../profiles/index.md#condition)) support [MiniMessage formatting](../profiles/formatting.md).
If you're unsure how a specific option should look like, head over to the [Profiles page](../profiles/index.md) for more information about the general structure.
All you need to know is, that a bare-bones server list profile requires a valid [priority](../profiles/index.md#priority) and at least one of the settings to be present.
@@ -351,16 +405,20 @@ motd:
To add additional profiles, create a new YAML file inside the `profiles` folder. The name doesn't matter, but it is recommended to keep it lowercase, use alphanumeric characters (`a-z, 0-9`), hyphens (`-`), underscores (`_`) and avoid spaces.
Inside the file, add a priority and at least one setting, similar to the above shown example.
This would already be enough and AdvancedServerList would use it. If you however want to only show it when certain conditions are met, should you set the priority to a higher value and add conditions.
This would already be enough to have a valid profile, but depending on the priority and file name may the file not be used, or used over other profiles.
Conditions can be multiple strings containing [operands](../profiles/index.md#operands) to evaluate them. As an example `${server playersOnline} >= 10` would return true if the current number of online players is larger or equal to 10.
If you want to only show this file under specific situations can you use the [`condition`](../profiles/index.md#condition) option to apply conditions that need to be met to show the profile.
The condition option would have a single String containing one or muliple [Expressions](../profiles/expressions.md). Only if the condition would return true, would the profile be displayed, granted that it has a higher priority than any other valid file with a true condition output.
Here is another example profile using conditions:
/// info | Note
Profiles which do not have any conditions, or have an empty condition, will always considered to have a true condition, meaning that a profile with higher priority and no condition will be selected over a profile with lower priority and a condition, even if said condition returns true.
///
Here is another example profile using conditions to show it when the player was banned on the server:
```yaml title="other_profile.yml"
priority: 1
conditions:
- '${player isBanned} = true'
condition: '${player isBanned}'
motd:
- '<red>You got <bold>banned</bold> from this server.'
+7
View File
@@ -0,0 +1,7 @@
nav:
- index.md
- v3_8_0-to-v3_9_0.md
- v3_7_0-to-v3_8_0.md
- pre-v3_7_0-to-v3_7_0.md
- v1_9_0-to-v1_10_0.md
- v1_5_3-to-v1_6_0.md
+27 -1
View File
@@ -10,4 +10,30 @@ Note that these pages only cover server list profile files. The config.yml is au
## Pages
{nav}
<div class="grid cards" markdown>
- [**v3.7.0 to v3.8.0**](v3_7_0-to-v3_8_0.md)
----
Migrating from version 3.7.0 to 3.8.0.
- [**< v3.7.0 to v3.7.0**](pre-v3_7_0-to-v3_7_0.md)
----
Migrate from any version prior to 3.7.0 to 3.7.0 or newer.
- [**v1.9.0 to v1.10.0**](v1_9_0-to-v1_10_0.md)
----
Migrate from version 1.9.0 to 1.10.0.
- [**v1.5.3 to v1.6.0**](v1_5_3-to-v1_6_0.md)
----
Migrate from version 1.5.3 to 1.6.0.
</div>
@@ -2,7 +2,7 @@
icon: octicons/arrow-right-24
---
# < 3.7.0 to 3.7.0
# < v3.7.0 to v3.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.
+49
View File
@@ -0,0 +1,49 @@
---
icon: octicons/arrow-right-24
---
# v3.7.0 to v3.8.0
v3.8.0 brought a small yet important change to the condition system, which is the change of the "contains" operand from `<-` to `<_` to avoid possible issues with numbers.
## Migration
To migrate, switch any appearances of `<-` with `<_`
## Example
Here is a before and after example to help visualize the change:
/// tab | Before
```yaml
priority: 0
conditions: '${server host} <- "survival"'
motd:
- 'Welcome ${player name}!'
```
///
/// tab | After
```yaml
priority: 0
condition: '${server host} <_ "survival"'
motd:
- 'Welcome ${player name}!'
```
///
/// tab | Diff View
```diff
priority: 0
-condition: '${server host} <- "survival"'
+condition: '${server host} <_ "survival"'
motd:
- 'Welcome ${player name}!'
```
///
+49
View File
@@ -0,0 +1,49 @@
---
icon: octicons/arrow-right-24
---
# v3.8.0 to v3.9.0
v3.9.0 brings a small change to the `~=` operand by changing it to `=~` for sake of consistent pattern design. Additionally, was `~` added as a single-character equivalent to `=`.
## Migration
To migrate, switch any appearances of `~=` with `=~` or `~`.
## Example
Here is a before and after example to help visualize the change:
/// tab | Before
```yaml
priority: 0
conditions: '${player name} ~= "Someone"'
motd:
- 'Welcome ${player name}!'
```
///
/// tab | After
```yaml
priority: 0
condition: '${player name} =~ "Someone"'
motd:
- 'Welcome ${player name}!'
```
///
/// tab | Diff View
```diff
priority: 0
-condition: '${player name} ~= "Someone"'
+condition: '${player name} =~ "Someone"'
motd:
- 'Welcome ${player name}!'
```
///
+31 -19
View File
@@ -32,12 +32,14 @@ The following cases are considered literal values:
Any number is considered an expression, meaning the below examples are considered valid:
/// example | Examples
```
0
1000
-7
47.2
```
///
#### Strings
@@ -50,10 +52,12 @@ As an example, `Sand` would cause the expression engine to see `S AND` due to pa
To avoid this is it very important to always surround Strings with single or double quotes, as that tells the expression engine to treat as a String.
///
/// example | Examples
```
"Hello World!"
""
```
///
#### Booleans
@@ -63,6 +67,7 @@ Strings `true` and `false` are treated as boolean literals.
Any [placeholder](placeholders.md) is a valid expression.
/// example | Examples
```
${player protocol}
${player name}
@@ -70,6 +75,7 @@ ${player name}
${server playersOnline}
${server host}
```
///
### Binary Operators
@@ -77,23 +83,23 @@ ${server host}
The following binary operators can be used for boolean evaluation:
| Operator | True if |
|----------------------------------|-------------------------------------------------------------------------------------------------------------|
| `and` / `&&` | Both expressions return true. |
| `or` / <code>&#124;&#124;</code> | Either expression returns true. |
| `==` / `=` | Both expressions are equal (Case sensitive). |
| `~=` | Both expressions are equal (Not Case sensitive). |
| `!=` | Both expressions are not equal (Case sensitive). |
| `!~` | Both expressions are not equal (Not case sensitive). |
| <code>&#124;-</code> | Left expression starts with right expression. |
| <code>-&#124;</code> | Left expression ends with right expression. |
| `<-` | Left expression contains right expression. |
| `<` | Left expression is less than the right expression. Strings use their text length as number. |
| `<=` | Left expression is less than, or equal to, the right expression. Strings use their text length as number. |
| `>` | Left expression is larger than the right expression. Strings use their text length as number. |
| `>=` | Left expression is larger than, or equal to, the right expression. Strings use their text length as number. |
| Operator | True if |
|---------------|-------------------------------------------------------------------------------------------------------------|
| `and` / `&&` | Both expressions return true. |
| `or` / `\|\|` | Either expression returns true. |
| `==` / `=` | Both expressions are equal (Case sensitive). |
| `=~` / `~` | Both expressions are equal (Not Case sensitive). |
| `!=` | Both expressions are not equal (Case sensitive). |
| `!~` | Both expressions are not equal (Not case sensitive). |
| `\|-` | Left expression starts with right expression. |
| `-\|` | Left expression ends with right expression. |
| `<_` | Left expression contains right expression. |
| `<` | Left expression is less than the right expression. Strings use their text length as number. |
| `<=` | Left expression is less than, or equal to, the right expression. Strings use their text length as number. |
| `>` | Left expression is larger than the right expression. Strings use their text length as number. |
| `>=` | Left expression is larger than, or equal to, the right expression. Strings use their text length as number. |
Additionally can these additional binary operators used for specific actions:
These additional binary operators can also be used to perform certain actions:
| Operator | Semantic |
|----------|-----------------------------------------------------------------------------|
@@ -103,10 +109,17 @@ Additionally can these additional binary operators used for specific actions:
| `*` | Multiplies two numbers. Strings use their text length as number. |
| `/` | Divides one number by another. Strings use their text length as number. |
/// example | Examples
```
${player name} != "Anonymous"
763 > ${player protocol} > 758
${player hasPlayedBefore} and ${player isBanned} == "false"
```
///
### Parenthesis
`( <expression> )` is a valid expression.
Parenthesis can be used to prevent ambiguities.
### Negation
@@ -119,5 +132,4 @@ Parenthesis can be used to prevent ambiguities.
## Credits
This page, including examples used, was adobted from the BungeeTabListPlus wiki.
The original wiki page can be found here: https://github.com/CodeCrafter47/BungeeTabListPlus/wiki/Expressions
This page, including some examples used, was adobted from [:octicons-book-24: CodeCrafter47/BungeeTabListPlus/wiki](https://github.com/CodeCrafter47/BungeeTabListPlus/wiki/Expressions){ target="_blank" rel="nofollow" }.
+12 -2
View File
@@ -38,8 +38,18 @@ The following options are **not** supported, no matter what option they are used
## Colors
Color options (`<aqua>`, `<red>`, `<gray>`, etc.) are available for all text options.
24-Bit HEX colors (`<#ff0000>`, `<#123abc>`, etc.) are only available for the [`Motd` option](../index.md#motd) for a 1.16+ Server/Proxy.
### Default colors
Default colors such as `<red>`, `<green>`, `<aqua>`, etc. may be used in all text options.
### Hex Colors
Hexadecimal colors may be used in the [`motd`](index.md#motd) option using the `<#RRGGBB>` format.
### Gradients
Gradients can be created by using `<gradient:<color1>:<color2>>`, replacing `<color1>` with a starting color name or hex color value and `<color2>` with an ending color name or hex color value.
Only the [`motd`](index.md#motd) option may support hex color gradients and in all other options will it be downsampled.
## Formatting
-27
View File
@@ -40,33 +40,6 @@ Not setting this option, or setting it to an empty String (`condition: ''`), wil
The condition option can hold one or multiple expressions. The Expression system is explained on the [Expressions page](expressions.md).
## Conditions :octicons-trash-24:{ style="color: #FF5252;" title="Deprecated" }
<!-- admo:deprecated Deprecated in favour of the new condition option. Will be removed in a future version. -->
The `conditions` option - not to be confused with the new [`condition`](#condition) option - allows you to define one or multiple conditions/expressions that all need to return `true` in order for the profile to be used.
Not setting this option, or setting it to an empty list (`conditions: []`), will result in `true` being returned.
Each condition can use [placeholders](placeholders.md) to further customize it. PlaceholderAPI placeholders are **not** supported!
### Operands
<!-- admo:warning Each condition can only hold one operand -->
Each condition can use operands to compare values with each other.
Note that if Operands are used that compare sizes (i.e. `>`) while the values are Text and not numbers will the text length be used as number.
| Operand | What it does |
|---------|----------------------------------------------------------------------------|
| `<` | Returns true if the left value is less than the right value. |
| `<=` | Returns true if the left value is less than, or equal to, the right value. |
| `>` | Returns true if the left value is more than the right value. |
| `>=` | Returns true if the left value is less than, or equal to, the right value. |
| `=` | Returns true if both values are equal (Case sensitive). |
| `!=` | Returns true if both values are not equal (Case sensitive). |
| `~=` | Returns true if both values are equal (Not case sensitive). |
| `!~` | Returns true if both values are not equal (Not case sensitive). |
## Profiles
The `profile` option allows you to define a list of all other options, with the exception of [`priority`](#priority), [`condition`](#condition) or itself.
+1
View File
@@ -106,3 +106,4 @@ markdown_extensions:
hooks:
- docs/.hooks/badges.py
- docs/.hooks/replacer.py
+1 -9
View File
@@ -48,14 +48,6 @@
<id>papermc</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
<repository>
<id>spigot</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>protocollib-repo</id>
<url>https://repo.dmulloy2.net/repository/public/</url>
</repository>
<repository>
<id>placeholderapi-repo</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
@@ -125,7 +117,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<version>3.5.2</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
@@ -42,6 +42,7 @@ import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.CachedServerIcon;
import java.awt.image.BufferedImage;
import java.nio.file.Path;
public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon>{
@@ -107,12 +108,17 @@ public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon
));
}
@Override
public void loadFaviconHandler(AdvancedServerList<CachedServerIcon> core){
faviconHandler = new FaviconHandler<>(core);
}
@Override
public void clearFaviconCache(){
if(faviconHandler == null)
return;
faviconHandler.clearCache();
faviconHandler.cleanCache();
}
@Override
@@ -153,6 +159,11 @@ public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon
return "paper";
}
@Override
public CachedServerIcon createFavicon(BufferedImage image) throws Exception{
return Bukkit.loadServerIcon(image);
}
public WorldCache getWorldCache(){
if(worldCache != null)
return worldCache;
@@ -171,11 +182,11 @@ public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon
getPluginLogger().warn(" - Reliance on a different plugin for core functionalities.");
getPluginLogger().warn(" - Bad dependency loading limited to MavenCentral only.");
getPluginLogger().warn("");
getPluginLogger().warn("Please consider switching to Paper or one of the Paper-compatible forks to benefit from");
getPluginLogger().warn("overall performance improvements amongst other things.");
getPluginLogger().warn("Please consider switching to Paper or one of the Paper-compatible forks to benefit");
getPluginLogger().warn("from overall performance improvements amongst other things.");
getPluginLogger().warn("");
getPluginLogger().warn("AdvancedServerList will now disable itself. If you believe this was a mistake, report");
getPluginLogger().warn("this on Codeberg: https://codeberg.org/Andre601/AdvancedServerList");
getPluginLogger().warn("Disabling AdvancedServerList. If you believe this is an error, report it on");
getPluginLogger().warn("Codeberg: https://codeberg.org/Andre601/AdvancedServerList");
getPluginLogger().warn("======================================================================================");
Bukkit.getPluginManager().disablePlugin(this);
@@ -45,8 +45,9 @@ import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.util.CachedServerIcon;
import java.awt.image.BufferedImage;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon, PaperPlayerImpl>{
@@ -186,9 +187,4 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
public GenericServer createGenericServer(int playersOnline, int playersMax, String host){
return new PaperServerImpl(plugin.getWorldCache().worlds(), playersOnline, playersMax, host);
}
@Override
public CachedServerIcon createFavicon(BufferedImage image) throws Exception{
return Bukkit.loadServerIcon(image);
}
}
+2 -1
View File
@@ -38,7 +38,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.commit/>
<plugin.version>3.7.0</plugin.version>
<plugin.version>4.2.0</plugin.version>
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
<api.version>v3.1.0</api.version>
@@ -60,5 +60,6 @@
<module>paper</module>
<module>velocity</module>
<module>version-uploader</module>
<module>addons/banplugins</module>
</modules>
</project>
+2 -1
View File
@@ -12,7 +12,8 @@
"ch.andre601.asl-api:platform-bukkit",
"ch.andre601.asl-api:platform-bungeecord",
"ch.andre601.asl-api:platform-velocity",
"ch.andre601.asl-api:api"
"ch.andre601.asl-api:api",
"com.github.DevLeoko:AdvancedBan"
],
"registryUrls": [
"https://jitpack.io"
+1 -1
View File
@@ -1,4 +1,4 @@
mkdocs-material==9.5.6
mkdocs-material==9.5.10
mkdocs-glightbox==0.3.7
mkdocs-awesome-pages-plugin==2.9.2
git+https://github.com/Andre601/mkdocs-pagenav-generator
Loaded 100 of 109 files, more files were not shown because too many files have changed in this diff. Show more