Compare commits

...
35 Commits
Author SHA1 Message Date
Andre601 38e16f1d4b Bump version to 4.3.0 2024-03-03 00:14:42 +01:00
Andre601 2e61531079 Merge pull request 'Add LibertyBans' (#233) from feature/libertybans-addon into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/233
2024-03-02 23:12:05 +00:00
Andre601 5cf295d4c5 Merge branch 'master' into feature/libertybans-addon 2024-03-02 23:08:55 +00:00
Andre601 24d5865a57 Also add asl parent 2024-03-03 00:08:17 +01:00
Andre601 03c5e7d9d0 Add ExpressionParser to matchPackageNames 2024-03-03 00:08:17 +01:00
Andre601's Renovate Bot 7874fcf265 Update api.version to v3.2.1 2024-03-03 00:08:13 +01:00
Andre601 3e9070ebf9 Fix renovate.json 2024-03-03 00:06:12 +01:00
Andre601 478fa88a97 Also add asl parent 2024-03-02 12:10:33 +00:00
Andre601 346f94decc Add ExpressionParser to matchPackageNames 2024-03-02 12:09:06 +00:00
Andre601 f5e8a7e460 Merge pull request 'Update api.version to v3.2.1' (#237) from renovate/api.version into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/237
2024-03-02 12:06:58 +00:00
Andre601's Renovate Bot 3cb470a086 Update api.version to v3.2.1 2024-03-02 12:06:01 +00:00
Andre601 348ecce315 Fix renovate.json 2024-03-02 12:05:24 +00:00
Andre601 78463bca4f Merge branch 'master' into feature/libertybans-addon 2024-03-01 19:17:49 +00:00
Andre601 a6bde40f30 Update registry URL for asl API 2024-03-01 16:39:29 +00:00
Andre601 45fa7b5d69 Fix banExpiration placeholder using muteExpiration(player). 2024-03-01 16:18:34 +01:00
Andre601 1f52ff39d1 Update getting started guide 2024-02-29 16:06:42 +00:00
Andre601 bc66d925ff Merge pull request 'Update dependency mkdocs-material to v9.5.12' (#235) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/235
2024-02-29 12:25:20 +00:00
Andre601 41f8f6b29d Merge branch 'master' into renovate/mkdocs-material-9.x 2024-02-29 12:25:07 +00:00
Andre601 e032b2cc7f Merge pull request 'Update dependency ch.qos.logback:logback-classic to v1.5.1' (#234) from renovate/ch.qos.logback-logback-classic-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/234
2024-02-29 12:24:51 +00:00
Andre601's Renovate Bot 7c6d4a3840 Update dependency mkdocs-material to v9.5.12 2024-02-29 12:01:25 +00:00
Andre601's Renovate Bot 2f2095237d Update dependency ch.qos.logback:logback-classic to v1.5.1 2024-02-29 12:01:20 +00:00
Andre601 2a20af1f9a Update Javadoc link 2024-02-29 11:45:05 +01:00
Andre601 c424c5abd5 Use custom admonition for files 2024-02-28 15:55:31 +01:00
Andre601 101fc593d2 Update files 2024-02-28 15:50:41 +01:00
Andre601 cb9e65105e Add LibertyBans placeholder docs 2024-02-26 23:17:42 +01:00
Andre601 9b95bb1222 docs/api/index.md aktualisiert 2024-02-26 19:41:17 +00:00
Andre601 2b01ed9725 Use Collections.max and Update PlatformInfo 2024-02-26 20:29:45 +01:00
Andre601 9b77a1274d Update Link for api/source redirect 2024-02-26 17:49:01 +01:00
Andre601 18d5cca185 Update Repository URL for API 2024-02-26 17:48:32 +01:00
Andre601 d5b604c1d0 Add LibertyBans 2024-02-26 17:18:00 +01:00
Andre601 e9b4ccbb93 Merge pull request 'Update dependency mkdocs-material to v9.5.11' (#232) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/232
2024-02-24 12:03:07 +00:00
Andre601's Renovate Bot a14f8c961f Update dependency mkdocs-material to v9.5.11 2024-02-24 12:01:08 +00:00
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
96 changed files with 805 additions and 3269 deletions

No files matched your search

+16
View File
@@ -54,6 +54,10 @@
<id>papermc</id>
<url>https://papermc.io/repo/repository/maven-public/</url>
</repository>
<repository>
<id>libertybans</id>
<url>https://mvn-repo.arim.space/affero-gpl3/</url>
</repository>
</repositories>
<dependencies>
@@ -78,6 +82,12 @@
<version>1.20-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.velocitypowered</groupId>
<artifactId>velocity-api</artifactId>
<version>3.3.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- Plugin APIs -->
<dependency>
@@ -86,6 +96,12 @@
<version>v2.3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>space.arim.libertybans</groupId>
<artifactId>bans-api</artifactId>
<version>1.1.0-RC1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.andre601.asl-api</groupId>
<artifactId>api</artifactId>
@@ -27,13 +27,15 @@ package ch.andre601.advancedserverlist.banplugins.bungeecord;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.banplugins.placeholders.AdvancedBanPlaceholders;
import ch.andre601.advancedserverlist.banplugins.placeholders.LibertyBansPlaceholders;
import java.util.HashMap;
import java.util.Map;
public enum BungeeCordBanPlugins{
ADVANCED_BAN("AdvancedBan", new AdvancedBanPlaceholders());
ADVANCED_BAN("AdvancedBan", new AdvancedBanPlaceholders()),
LIBERTY_BANS("LibertyBans", new LibertyBansPlaceholders());
private final String plugin;
private final PlaceholderProvider placeholderProvider;
@@ -27,13 +27,15 @@ package ch.andre601.advancedserverlist.banplugins.paper;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.banplugins.placeholders.AdvancedBanPlaceholders;
import ch.andre601.advancedserverlist.banplugins.placeholders.LibertyBansPlaceholders;
import java.util.HashMap;
import java.util.Map;
public enum PaperBanPlugins{
ADVANCED_BAN("AdvancedBan", new AdvancedBanPlaceholders());
ADVANCED_BAN("AdvancedBan", new AdvancedBanPlaceholders()),
LIBERTY_BANS("LibertyBans", new LibertyBansPlaceholders());
private final String plugin;
private final PlaceholderProvider placeholderProvider;
@@ -0,0 +1,76 @@
/*
* 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.LibertyBansProvider;
import java.util.Arrays;
public class LibertyBansPlaceholders extends PlaceholderProvider{
private final LibertyBansProvider provider = LibertyBansProvider.create();
public LibertyBansPlaceholders(){
super("libertybans");
}
@Override
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
String[] args = placeholder.split("\\.");
return switch(args[0]){
// Mute-related placeholders
case "isMuted" -> String.valueOf(provider.muted(player));
case "muteReason" -> provider.muteReason(player);
case "muteExpiration" -> {
if(args.length == 1)
yield provider.muteExpirationDate(player);
String pattern = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
yield provider.muteExpirationDate(player, pattern);
}
// Ban-related placeholders
case "isBanned" -> String.valueOf(provider.banned(player));
case "banReason" -> provider.banReason(player);
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;
};
}
}
@@ -105,8 +105,7 @@ public class AdvancedBanProvider implements PunishmentProvider{
if(end < 0L)
return "never";
Date date = new Date(end);
return new SimpleDateFormat(pattern).format(date);
return this.returnDate(pattern, end);
}
@Override
@@ -119,8 +118,7 @@ public class AdvancedBanProvider implements PunishmentProvider{
if(end < 0L)
return "never";
Date date = new Date(end);
return new SimpleDateFormat(pattern).format(date);
return this.returnDate(pattern, end);
}
public String muteDuration(GenericPlayer player, boolean fromStart){
@@ -0,0 +1,136 @@
/*
* 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 space.arim.libertybans.api.LibertyBans;
import space.arim.libertybans.api.PunishmentType;
import space.arim.libertybans.api.punish.Punishment;
import space.arim.libertybans.api.user.KnownAccount;
import space.arim.omnibus.Omnibus;
import space.arim.omnibus.OmnibusProvider;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
public class LibertyBansProvider implements PunishmentProvider{
private final LibertyBans libertyBans;
private LibertyBansProvider(LibertyBans libertyBans){
this.libertyBans = libertyBans;
}
public static LibertyBansProvider create(){
Omnibus omnibus = OmnibusProvider.getOmnibus();
LibertyBans libertyBans = omnibus.getRegistry().getProvider(LibertyBans.class).orElseThrow();
return new LibertyBansProvider(libertyBans);
}
@Override
public boolean muted(GenericPlayer player){
return punishment(player.getUUID(), PunishmentType.MUTE) != null;
}
@Override
public boolean banned(GenericPlayer player){
return punishment(player.getUUID(), PunishmentType.BAN) != null;
}
@Override
public String muteReason(GenericPlayer player){
Punishment mute = punishment(player.getUUID(), PunishmentType.MUTE);
if(mute == null)
return null;
return mute.getReason();
}
@Override
public String banReason(GenericPlayer player){
Punishment ban = punishment(player.getUUID(), PunishmentType.BAN);
if(ban == null)
return null;
return ban.getReason();
}
@Override
public String muteDuration(GenericPlayer player){
return null;
}
@Override
public String banDuration(GenericPlayer player){
return null;
}
@Override
public String muteExpirationDate(GenericPlayer player, String pattern){
Punishment mute = punishment(player.getUUID(), PunishmentType.MUTE);
if(mute == null)
return null;
if(mute.isPermanent())
return "never";
return this.returnDate(pattern, mute.getEndDate().toEpochMilli());
}
@Override
public String banExpirationDate(GenericPlayer player, String pattern){
Punishment ban = punishment(player.getUUID(), PunishmentType.BAN);
if(ban == null)
return null;
if(ban.isPermanent())
return "never";
return this.returnDate(pattern, ban.getEndDate().toEpochMilli());
}
private Punishment punishment(UUID uuid, PunishmentType type){
List<? extends KnownAccount> accounts = libertyBans.getAccountSupervisor()
.findAccountsMatching(uuid)
.join();
if(accounts.isEmpty())
return null;
KnownAccount sorted = Collections.max(accounts, Comparator.comparing(KnownAccount::recorded));
return libertyBans.getSelector()
.selectionByApplicabilityBuilder(sorted.uuid(), sorted.address())
.type(type)
.build()
.getFirstSpecificPunishment()
.toCompletableFuture()
.join()
.orElse(null);
}
}
@@ -27,6 +27,9 @@ package ch.andre601.advancedserverlist.banplugins.providers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import java.text.SimpleDateFormat;
import java.util.Date;
public interface PunishmentProvider{
boolean muted(GenericPlayer player);
@@ -53,4 +56,13 @@ public interface PunishmentProvider{
String banExpirationDate(GenericPlayer player, String pattern);
default String returnDate(String pattern, long end){
Date date = new Date(end);
try{
return new SimpleDateFormat(pattern).format(date);
}catch(IllegalArgumentException ex){
return new SimpleDateFormat("dd, MMM yyyy HH:mm:ss").format(date);
}
}
}
@@ -23,27 +23,34 @@
*
*/
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
package ch.andre601.advancedserverlist.banplugins.velocity;
public interface ToBooleanExpression extends Expression{
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.banplugins.paper.PaperBanPlugins;
import ch.andre601.advancedserverlist.banplugins.placeholders.LibertyBansPlaceholders;
import java.util.HashMap;
import java.util.Map;
public enum VelocityBanPlugins{
boolean evaluate();
LIBERTY_BANS("libertybans", new LibertyBansPlaceholders());
static ToBooleanExpression literal(boolean value){
return new ConstantToBooleanExpression(value);
private final String plugin;
private final PlaceholderProvider placeholderProvider;
VelocityBanPlugins(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(VelocityBanPlugins velocityBanPlugins : VelocityBanPlugins.values()){
content.put(velocityBanPlugins.plugin, velocityBanPlugins.placeholderProvider);
}
@Override
public boolean evaluate(){
return value;
}
return content;
}
}
@@ -0,0 +1,82 @@
/*
* 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.velocity;
import ch.andre601.advancedserverlist.api.AdvancedServerListAPI;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import com.google.inject.Inject;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import net.md_5.bungee.api.ProxyServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
public class VelocityBanPluginsAddon{
private final Logger logger = LoggerFactory.getLogger("ASLBanPluginsAddon");
private final ProxyServer proxy;
@Inject
public VelocityBanPluginsAddon(ProxyServer proxy){
this.proxy = proxy;
}
@Subscribe
public void init(ProxyInitializeEvent event){
if(proxy.getPluginManager().getPlugin("advancedserverlist") == null){
logger.warn("AdvancedServerList is not enabled. This plugin requires it to function!");
return;
}
int loadedPlaceholders = loadPlaceholderProviders();
if(loadedPlaceholders == 0){
logger.warn("No compatible Ban plugin was found to register placeholders for.");
}else{
logger.info("Loaded {} Placeholder Set(s) for AdvancedServerList!", loadedPlaceholders);
}
}
private int loadPlaceholderProviders(){
int loaded = 0;
Map<String, PlaceholderProvider> banPlugins = VelocityBanPlugins.getBanPlugins();
AdvancedServerListAPI api = AdvancedServerListAPI.get();
for(Map.Entry<String, PlaceholderProvider> entry : banPlugins.entrySet()){
if(proxy.getPluginManager().getPlugin(entry.getKey()) != null){
logger.info("Registering placeholders for {}...", entry.getKey());
api.addPlaceholderProvider(entry.getValue());
logger.info("Placeholder successfully registered!");
loaded++;
}
}
return loaded;
}
}
@@ -6,5 +6,6 @@ description: 'AdvancedBan Add-on for AdvancedServerList to add placeholders to u
softDepends:
- AdvancedServerList
- AdvancedBan
- LibertyBans
main: 'ch.andre601.advancedserverlist.banplugins.bungeecord.BungeeCordBanPluginsAddon'
@@ -12,5 +12,8 @@ dependencies:
required: false
load: BEFORE
AdvancedBans:
required: false
load: BEFORE
LibertyBans:
required: false
load: BEFORE
@@ -0,0 +1,20 @@
{
"id": "aslbanpluginsaddon",
"name": "ASLBanPluginsAddon",
"version": "${plugin.version}",
"description": "${plugin.description}",
"authors": [
"Andre_601"
],
"dependencies": [
{
"id": "advancedserverlist",
"optional": true
},
{
"id": "libertybans",
"optional": true
}
],
"main": "ch.andre601.advancedserverlist.banplugins.velocity.VelocityBanPluginsAddon"
}
@@ -29,8 +29,8 @@ import ch.andre601.advancedserverlist.bungeecord.commands.CmdAdvancedServerList;
import ch.andre601.advancedserverlist.bungeecord.listeners.JoinEvent;
import ch.andre601.advancedserverlist.bungeecord.listeners.PingEvent;
import ch.andre601.advancedserverlist.bungeecord.logging.BungeeLogger;
import ch.andre601.advancedserverlist.bungeecord.objects.BungeePlayerPlaceholders;
import ch.andre601.advancedserverlist.bungeecord.objects.BungeeServerPlaceholders;
import ch.andre601.advancedserverlist.bungeecord.objects.placeholders.BungeePlayerPlaceholders;
import ch.andre601.advancedserverlist.bungeecord.objects.placeholders.BungeeServerPlaceholders;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
@@ -29,8 +29,8 @@ 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.bungeecord.objects.BungeeProxyImpl;
import ch.andre601.advancedserverlist.bungeecord.objects.impl.BungeePlayerImpl;
import ch.andre601.advancedserverlist.bungeecord.objects.impl.BungeeProxyImpl;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,7 @@
*
*/
package ch.andre601.advancedserverlist.bungeecord.objects;
package ch.andre601.advancedserverlist.bungeecord.objects.impl;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayerImpl;
@@ -31,8 +31,8 @@ import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayerImpl;
public class BungeePlayerImpl extends GenericPlayerImpl{
public BungeePlayerImpl(CachedPlayer player, int protocol){
this.name = player.getName();
this.name = player.name();
this.protocol = protocol;
this.uuid = player.getUuid();
this.uuid = player.uuid();
}
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,7 @@
*
*/
package ch.andre601.advancedserverlist.bungeecord.objects;
package ch.andre601.advancedserverlist.bungeecord.objects.impl;
import ch.andre601.advancedserverlist.api.bungeecord.objects.BungeeProxy;
import net.md_5.bungee.api.config.ServerInfo;
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,7 @@
*
*/
package ch.andre601.advancedserverlist.bungeecord.objects;
package ch.andre601.advancedserverlist.bungeecord.objects.placeholders;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,7 @@
*
*/
package ch.andre601.advancedserverlist.bungeecord.objects;
package ch.andre601.advancedserverlist.bungeecord.objects.placeholders;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.bungeecord.objects.BungeeProxy;
+14
View File
@@ -57,6 +57,10 @@
<id>sonatype</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
<repository>
<id>codeberg</id>
<url>https://codeberg.org/api/packages/Andre601/maven/</url>
</repository>
</repositories>
<dependencies>
@@ -66,6 +70,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>
@@ -168,6 +178,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,7 +31,7 @@ import ch.andre601.advancedserverlist.core.check.UpdateChecker;
import ch.andre601.advancedserverlist.core.commands.CommandHandler;
import ch.andre601.advancedserverlist.core.file.FileHandler;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionEngine;
import ch.andre601.advancedserverlist.core.profiles.conditions.ProfileConditionParser;
import ch.andre601.advancedserverlist.core.profiles.players.PlayerHandler;
import java.io.IOException;
@@ -47,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;
@@ -92,8 +92,8 @@ public class AdvancedServerList<F>{
return api;
}
public ExpressionEngine getExpressionEngine(){
return expressionEngine;
public ProfileConditionParser getParser(){
return parser;
}
public void disable(){
@@ -27,28 +27,4 @@ package ch.andre601.advancedserverlist.core.objects;
import java.util.UUID;
@SuppressWarnings("FieldMayBeFinal")
public class CachedPlayer{
private String ip;
private String name;
private UUID uuid;
public CachedPlayer(String ip, String name, UUID uuid){
this.ip = ip;
this.name = name;
this.uuid = uuid;
}
public String getIp(){
return ip;
}
public String getName(){
return name;
}
public UUID getUuid(){
return uuid;
}
}
public record CachedPlayer(String ip, String name, UUID uuid){}
@@ -29,9 +29,9 @@ 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.expressions.ExpressionEngine;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
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;
@@ -42,21 +42,29 @@ import java.util.Random;
public record ServerListProfile(int priority, String condition, ProfileEntry defaultProfile, List<ProfileEntry> profiles){
private static final Random random = new Random();
public boolean evalConditions(ExpressionEngine expressionEngine, PluginLogger logger, GenericPlayer player, GenericServer server){
public boolean evalConditions(ProfileConditionParser parser, PluginLogger logger, GenericPlayer player, GenericServer server){
if(condition == null || condition.isEmpty())
return true;
ExpressionsWarnHelper warnHelper = new ExpressionsWarnHelper(condition);
ExpressionTemplate template = expressionEngine.compile(condition, player, server, warnHelper);
ParseWarnCollector collector = new ParseWarnCollector(condition);
ExpressionTemplate template = parser.compile(condition, player, server, collector);
if(warnHelper.hasWarnings()){
warnHelper.printWarnings(logger);
if(collector.hasWarnings()){
logger.warn("Encountered %d Error(s) while parsing condition '%s':", collector.getWarnings().size(), condition);
if(template == null)
return false;
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 template.instantiateWithBooleanResult().evaluate();
if(template == null)
return false;
return template.returnBooleanExpression().evaluate();
}
public ProfileEntry getRandomProfile(){
@@ -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.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, GenericPlayer player, GenericServer server, ExpressionsWarnHelper warnHelper){
return templateParser.parse(tokenizer.parse(expression, player, server, warnHelper), warnHelper);
}
public static class Options{
private final List<TokenReader> tokenReaders;
private final ImmutableMap<Token, Operator> operators;
private final ImmutableList<ValueReader> valueReaders;
private Options(List<TokenReader> tokenReaders, ImmutableMap<Token, Operator> operators, ImmutableList<ValueReader> valueReaders){
this.tokenReaders = tokenReaders;
this.operators = operators;
this.valueReaders = valueReaders;
}
public static class Builder{
private final List<TokenReader> tokenReaders = new ArrayList<>();
private final Map<Token, Operator> operators = new HashMap<>();
private final List<ValueReader> valueReaders = new ArrayList<>();
public Builder(){}
public Builder withDefaultTokenReaders(){
return this
.tokenReader(new PatternTokenReader(BooleanToken.FALSE, "false"))
.tokenReader(new PatternTokenReader(BooleanToken.TRUE, "true"))
.tokenReader(new PatternTokenReader(DefaultTokens.AND, "and"))
.tokenReader(new PatternTokenReader(DefaultTokens.AND, "&&"))
.tokenReader(new PatternTokenReader(DefaultTokens.OR, "or"))
.tokenReader(new PatternTokenReader(DefaultTokens.OR, "||"))
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL, "=="))
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL_IGNORE_CASE, "=~"))
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL, "="))
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL_IGNORE_CASE, "~"))
.tokenReader(new PatternTokenReader(DefaultTokens.NOT_EQUAL, "!="))
.tokenReader(new PatternTokenReader(DefaultTokens.NOT_EQUAL_IGNORE_CASE, "!~"))
.tokenReader(new PatternTokenReader(DefaultTokens.STARTS_WITH, "|-"))
.tokenReader(new PatternTokenReader(DefaultTokens.ENDS_WITH, "-|"))
.tokenReader(new PatternTokenReader(DefaultTokens.CONTAINS, "<_"))
.tokenReader(new PatternTokenReader(DefaultTokens.GREATER_OR_EQUAL_THAN, ">="))
.tokenReader(new PatternTokenReader(DefaultTokens.LESSER_OR_EQUAL_THAN, "<="))
.tokenReader(new PatternTokenReader(DefaultTokens.OPENING_PARENTHESIS, "("))
.tokenReader(new PatternTokenReader(DefaultTokens.CLOSING_PARENTHESIS, ")"))
.tokenReader(new PatternTokenReader(DefaultTokens.NEGATION, "!"))
.tokenReader(new PatternTokenReader(DefaultTokens.GREATER_THAN, ">"))
.tokenReader(new PatternTokenReader(DefaultTokens.LESSER_THAN, "<"))
.tokenReader(new PatternTokenReader(DefaultTokens.CONCAT_STRING, "."))
.tokenReader(new PatternTokenReader(DefaultTokens.ADD, "+"))
.tokenReader(new PatternTokenReader(DefaultTokens.SUB, "-"))
.tokenReader(new PatternTokenReader(DefaultTokens.MULT, "*"))
.tokenReader(new PatternTokenReader(DefaultTokens.DIV, "/"))
.tokenReader(new QuotedLiteralTokenReader(-10, '\"'))
.tokenReader(new QuotedLiteralTokenReader(-10, '\''))
.tokenReader(new PlaceholderTokenReader(-20))
.tokenReader(new NumberTokenReader(-50))
.tokenReader(new NonQuotedLiteralTokenReader(-100));
}
public Builder withDefaultOperators(){
return this
.operator(DefaultTokens.AND, ListOperator.of(100, ExpressionTemplates::and))
.operator(DefaultTokens.OR, ListOperator.of(50, ExpressionTemplates::or))
.operator(DefaultTokens.EQUAL, Operator.of(25, ExpressionTemplates::equal))
.operator(DefaultTokens.NOT_EQUAL, Operator.of(25, ExpressionTemplates::notEqual))
.operator(DefaultTokens.EQUAL_IGNORE_CASE, Operator.of(25, ExpressionTemplates::equalIgnoreCase))
.operator(DefaultTokens.NOT_EQUAL_IGNORE_CASE, Operator.of(25, ExpressionTemplates::notEqualIgnoreCase))
.operator(DefaultTokens.STARTS_WITH, Operator.of(25, ExpressionTemplates::startsWith))
.operator(DefaultTokens.ENDS_WITH, Operator.of(25, ExpressionTemplates::endsWith))
.operator(DefaultTokens.CONTAINS, Operator.of(25, ExpressionTemplates::contains))
.operator(DefaultTokens.GREATER_THAN, Operator.of(25, ExpressionTemplates::greater))
.operator(DefaultTokens.GREATER_OR_EQUAL_THAN, Operator.of(25, ExpressionTemplates::greaterOrEqual))
.operator(DefaultTokens.LESSER_THAN, Operator.of(25, ExpressionTemplates::less))
.operator(DefaultTokens.LESSER_OR_EQUAL_THAN, Operator.of(25, ExpressionTemplates::lessOrEqual))
.operator(DefaultTokens.CONCAT_STRING, ListOperator.of(10, ExpressionTemplates::concat))
.operator(DefaultTokens.ADD, ListOperator.of(4, ExpressionTemplates::sum))
.operator(DefaultTokens.SUB, Operator.of(3, ExpressionTemplates::sub))
.operator(DefaultTokens.MULT, ListOperator.of(2, ExpressionTemplates::product))
.operator(DefaultTokens.DIV, Operator.of(1, ExpressionTemplates::div));
}
public Builder withDefaultValueReaders(){
return this
.valueReader(new BooleanConstantReader())
.valueReader(new NumberConstantReader())
.valueReader(new StringConstantReader())
.valueReader(new NegatedExpressionReader(DefaultTokens.NEGATION))
.valueReader(new ParenthesisedExpressionReader(DefaultTokens.OPENING_PARENTHESIS, DefaultTokens.CLOSING_PARENTHESIS))
.valueReader(new PlaceholderReader())
.valueReader(new NegatedNumberReader(DefaultTokens.SUB));
}
public Builder tokenReader(TokenReader tokenReader){
this.tokenReaders.add(tokenReader);
return this;
}
public Builder operator(Token token, Operator operator){
this.operators.put(token, operator);
return this;
}
public Builder valueReader(ValueReader valueReader){
this.valueReaders.add(valueReader);
return this;
}
public Options build(){
return new Options(this.tokenReaders, ImmutableMap.copyOf(operators), ImmutableList.copyOf(valueReaders));
}
}
}
}
@@ -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,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.expressions;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import java.util.ArrayList;
import java.util.List;
public class ExpressionsWarnHelper{
private final String expression;
private final List<Context> warnings = new ArrayList<>();
public ExpressionsWarnHelper(String expression){
this.expression = expression;
}
public void appendWarning(int position, String warning, Object... args){
warnings.add(new Context(position, String.format(warning, args)));
}
public boolean hasWarnings(){
return !warnings.isEmpty();
}
public void printWarnings(PluginLogger logger){
logger.warn("Encountered %d issue(s) while parsing expression '%s'", warnings.size(), expression);
for(Context warning : warnings){
if(warning.position() > -1){
logger.warn(" - At Position %d: %s", warning.position(), warning.message());
}else{
logger.warn(" - Cause: %s", warning.message());
}
}
}
public record Context(int position, String message){}
}
@@ -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 ToDoubleExpression extends Expression{
double evaluate();
static ToDoubleExpression literal(double value){
return new ConstantToDoubleExpression(value);
}
class ConstantToDoubleExpression implements ToDoubleExpression{
private final double value;
public ConstantToDoubleExpression(double value){
this.value = value;
}
@Override
public double evaluate(){
return value;
}
}
}
@@ -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,54 +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.function.BiFunction;
public abstract class Operator{
private final int priority;
public Operator(int priority){
this.priority = priority;
}
public static Operator of(int priority, BiFunction<ExpressionTemplate, ExpressionTemplate, ExpressionTemplate> function){
return new Operator(priority){
@Override
public ExpressionTemplate createTemplate(ExpressionTemplate a, ExpressionTemplate b){
return function.apply(a, b);
}
};
}
public int getPriority(){
return priority;
}
public abstract ExpressionTemplate createTemplate(ExpressionTemplate a, ExpressionTemplate b);
}
@@ -1,45 +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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper){
if(tokenList.get(0) instanceof BooleanToken){
return ConstantExpressionTemplate.of(((BooleanToken)tokenList.remove(0)).getValue());
}
return null;
}
}
@@ -1,137 +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.expressions.ExpressionsWarnHelper;
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.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, ExpressionsWarnHelper warnHelper){
List<ExpressionTemplate> parts = new ArrayList<>();
List<Operator> operators = new ArrayList<>();
try{
parts.add(read(tokenList, warnHelper));
}catch(IllegalArgumentException ex){
warnHelper.appendWarning(-1, ex.getMessage());
return null;
}
while(!tokenList.isEmpty()){
Token token = tokenList.remove(0);
Operator operator = this.operators.get(token);
if(operator == null){
warnHelper.appendWarning(-1, "Received \"%s\" but expected OPERATOR.", token);
return null;
}
operators.add(operator);
if(tokenList.isEmpty()){
warnHelper.appendWarning(-1, "Received unexpected end of input.");
return null;
}
try{
parts.add(read(tokenList, warnHelper));
}catch(IllegalArgumentException ex){
warnHelper.appendWarning(-1, ex.getMessage());
return null;
}
}
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, ExpressionsWarnHelper warnHelper){
for(ValueReader valueReader : valueReaders){
ExpressionTemplate template = valueReader.read(this, tokenList, warnHelper);
if(template != null)
return template;
}
throw new IllegalArgumentException("Invalid Expression. Expected literal but got token \"" + tokenList.get(0).toString() + "\"");
}
}
@@ -1,52 +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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper){
if(tokenList.get(0) == tokenNegation){
tokenList.remove(0);
return ExpressionTemplates.negate(parser.read(tokenList, warnHelper));
}
return null;
}
}
@@ -1,52 +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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper){
if(tokenList.get(0) == tokenNegation){
tokenList.remove(0);
return ExpressionTemplates.negateNumber(parser.read(tokenList, warnHelper));
}
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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper){
if(tokenList.get(0) instanceof NumberToken){
return ConstantExpressionTemplate.of(((NumberToken)tokenList.remove(0)).getValue());
}
return null;
}
}
@@ -1,72 +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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper){
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)), warnHelper);
tokenList.subList(0, index + 1).clear();
return result;
}
return null;
}
}
@@ -1,45 +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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper){
if(tokenList.get(0) instanceof StringToken){
return ConstantExpressionTemplate.of(((StringToken)tokenList.remove(0)).getValue());
}
return null;
}
}
@@ -1,37 +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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper);
}
@@ -1,73 +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){
double doubleValue;
try{
doubleValue = Double.parseDouble(value);
}catch(NumberFormatException ex){
doubleValue = value.length();
}
return new LiteralPlaceholderValue(value, doubleValue, Boolean.parseBoolean(value));
}
class LiteralPlaceholderValue implements Placeholder{
private final String stringValue;
private final double doubleValue;
private final boolean booleanValue;
public LiteralPlaceholderValue(String stringValue, double doubleValue, boolean booleanValue){
this.stringValue = stringValue;
this.doubleValue = doubleValue;
this.booleanValue = booleanValue;
}
@Override
public ToStringExpression instantiateWithStringResult(){
return ToStringExpression.literal(stringValue);
}
@Override
public ToDoubleExpression instantiateWithDoubleResult(){
return ToDoubleExpression.literal(doubleValue);
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return ToBooleanExpression.literal(booleanValue);
}
}
}
@@ -29,14 +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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper){
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();
@@ -48,6 +53,7 @@ public class PlaceholderParser{
char[] chars = text.substring(index).toCharArray();
for(final char c : chars){
index++;
if(c == '}'){
invalid = false;
break;
@@ -70,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){
@@ -78,9 +85,8 @@ public class PlaceholderParser{
if(identified)
raw.append(' ').append(valuesStr);
warnHelper.appendWarning(index, "Placeholder '%s' does not have a closing bracket (}).",raw.toString());
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);
@@ -90,12 +96,10 @@ public class PlaceholderParser{
if(identified)
raw.append(' ').append(valuesStr);
raw.append('}');
warnHelper.appendWarning(index, "Placeholder '%s' does not have an available PlaceholderProvider.", raw.toString());
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);
@@ -107,11 +111,10 @@ public class PlaceholderParser{
raw.append('}');
warnHelper.appendWarning(index, "Placeholder '%s' returned a null value.", raw.toString());
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,26 +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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper);
public abstract Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server, ParseWarnCollector collector);
}
@@ -23,28 +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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper){
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, warnHelper));
return new PlaceholderToken(PlaceholderParser.parse(text, position, player, server, collector));
}
return null;
}
@@ -23,20 +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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper){
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.profiles.conditions.expressions.ExpressionsWarnHelper;
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, GenericPlayer player, GenericServer server, ExpressionsWarnHelper warnHelper){
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, warnHelper))){
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;
}
}
}
warnHelper.appendWarning(position.getIndex(), "Illegal token '%c'.", text.charAt(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,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 StringToken extends Token{
private final String value;
public StringToken(String value){
super("STRING(" + value + ")");
this.value = value;
}
public String 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,54 +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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper){
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,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.tokens.readers;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper){
int previous = position.getIndex();
Number number = format.parse(text, position);
if(position.getIndex() != previous)
return new NumberToken(number.doubleValue());
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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper){
if(text.regionMatches(ignoreCase, position.getIndex(), pattern, 0, pattern.length())){
position.setIndex(position.getIndex() + pattern.length());
return token;
}
return null;
}
}
@@ -1,63 +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.expressions.ExpressionsWarnHelper;
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, ExpressionsWarnHelper warnHelper){
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;
}
}
@@ -29,6 +29,8 @@ import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import com.google.gson.Gson;
import com.google.gson.JsonIOException;
import com.google.gson.JsonSyntaxException;
import io.leangen.geantyref.TypeToken;
import java.io.BufferedReader;
@@ -70,19 +72,18 @@ public class PlayerHandler{
}
if(core.getFileHandler().getBoolean("disableCache")){
logger.info("'disable_cache' is set to true. Skipping playercache.json loading...");
logger.info("'disableCache' is set to true. Skipping playercache.json loading...");
return;
}
try{
BufferedReader reader = Files.newBufferedReader(cache);
try(BufferedReader reader = Files.newBufferedReader(cache)){
cachedPlayers = gson.fromJson(reader, listType);
reader.close();
}catch(IOException ex){
logger.warn("Encountered IOException while reading the playercache.json file!", ex);
return;
}catch(JsonIOException | JsonSyntaxException ex){
logger.warn("Encountered Json exception while parsing playercache.json file!", ex);
return;
}
// In case Gson messes up... I guess.
@@ -129,7 +130,7 @@ public class PlayerHandler{
return getDefaultPlayer();
for(CachedPlayer player : cachedPlayers){
if(player.getIp().equals(key))
if(player.ip().equals(key))
return player;
}
@@ -138,7 +139,7 @@ public class PlayerHandler{
public CachedPlayer getCachedPlayer(UUID uuid){
for(CachedPlayer player : cachedPlayers){
if(player.getUuid().equals(uuid))
if(player.uuid().equals(uuid))
return player;
}
@@ -152,7 +153,7 @@ public class PlayerHandler{
private boolean contains(String ip){
for(CachedPlayer player : cachedPlayers){
if(player.getIp().equals(ip))
if(player.ip().equals(ip))
return true;
}
@@ -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,8 +25,9 @@
package ch.andre601.advancedserverlist.test;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionEngine;
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
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;
@@ -35,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();
@@ -44,8 +45,15 @@ public class ExpressionParserTests{
for(Map.Entry<String, Boolean> values : testValuesMap.entrySet()){
logger.info("TEST[expression=\"%s\", expected=%b]", values.getKey(), values.getValue());
ExpressionsWarnHelper warnHelper = new ExpressionsWarnHelper(values.getKey());
boolean result = expressionEngine.compile(values.getKey(), null, null, warnHelper).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());
}
+20
View File
@@ -32,6 +32,26 @@ Placeholders for the plugin [AdvancedBan](https://www.spigotmc.org/resources/869
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}`
### LibertyBans
Placeholders for the plugin [LibertyBans](https://modrinth.com/plugin/libertybans/){ target="_blank" rel="nofollow" } are available to use.
| Placeholder | Description |
|---------------------------------|------------------------------------------------------------------------------------------|
| `${libertybans isMuted}` | Whether the player is muted or not. |
| `${libertybans muteReason}` | The reason for why the player was muted. Returns invalid placeholder if no mute was set. |
| `${libertybans muteExpiration}` | Date on when the mute will expire.[^5] |
| `${libertybans isBanned}` | Whether the player is banned or not. |
| `${libertybans banReason}` | The reason for why the player was banned. Returns invalid placeholder if no ban was set. |
| `${libertybans banExpiration}` | Date on when the ban will expire.[^6] |
[^5]:
An optional Date and time Pattern can be set to change the displayed output. The default is `dd, MMM yyyy HH:mm:ss`.
Example: `${libertybans muteExpiration yyyy-MM-dd HH:mm:ss}`
[^6]:
An optional Date and time Pattern can be set to change the displayed output. The default is `dd, MMM yyyy HH:mm:ss`.
Example: `${libertybans banExpiration yyyy-MM-dd HH:mm:ss}`
## Example
```yaml title="banned.yml"
+5 -6
View File
@@ -4,8 +4,7 @@ icon: octicons/command-palette-24
# API
AdvancedServerList v2 introduced a new API that plugins can hook into to use.
It provides a way for your plugin to provide its own placeholders that should be parsed by AdvancedServerList and also an event to modify the server list.
AdvancedServerList offers an API that other plugins can use to add their own placeholder to the plugin, listen for specific events or even modify Server List Profiles on the fly.
## Add dependency
@@ -15,8 +14,8 @@ Add the following to your `pom.xml`, `build.gradle` or `build.gradle.kts` depend
```xml title="pom.xml"
<repositories>
<repository>
<id>jitpack</id>
<url>https://jitpack.io/</url>
<id>codeberg</id>
<url>https://codeberg.org/api/packages/Andre601/maven/</url>
</repository>
</repositories>
@@ -54,7 +53,7 @@ Add the following to your `pom.xml`, `build.gradle` or `build.gradle.kts` depend
/// tab | :simple-gradle: Gradle
```groovy title="build.gradle"
repositorories {
maven { url = 'https://jitpack.io/' }
maven { url = 'https://codeberg.org/api/packages/Andre601/maven/' }
}
dependencies {
@@ -71,7 +70,7 @@ dependencies {
/// tab | :simple-gradle: Gradle (KTS)
```kotlin title="build.gradle.kts"
repositories {
maven("https://jitpack.io")
maven("https://codeberg.org/api/packages/Andre601/maven/")
}
dependencies {
+1 -1
View File
@@ -1,7 +1,7 @@
---
template: redirect.html
location: https://docs.andre601.ch/asl-api
location: https://jd.andre601.ch
title: Javadocs
icon: octicons/link-external-24
+2 -2
View File
@@ -1,10 +1,10 @@
---
template: redirect.html
location: https://github.com/Andre601/asl-api
location: https://codeberg.org/Andre601/asl-api
title: Source Code
icon: octicons/mark-github-16
icon: simple/codeberg
---
<!-- Comment to trigger proper build -->
+6 -6
View File
@@ -1,5 +1,5 @@
document$.subscribe(async () => {
const url = 'https://codeberg-stats-proxy.vercel.app/repo'
const url = 'https://codeberg-stats-proxy.vercel.app'
const repo_stats = document.querySelector('[data-md-component="source"] .md-source__repository');
function loadCodebergInfo(data) {
@@ -31,7 +31,7 @@ document$.subscribe(async () => {
const versionToken = '{apiVersion}';
const codeBlocks = document.querySelectorAll('.md-content pre code');
for(const codeBlock of codeBlocks) {
codeBlock.innerHTML = codeBlock.innerHTML.replace(new RegExp(versionToken, 'g'), version);
codeBlock.innerHTML = codeBlock.innerHTML.replace(new RegExp(versionToken, 'g'), version.substring(1));
}
}
@@ -45,10 +45,10 @@ document$.subscribe(async () => {
}
async function fetchApiInfo() {
const tag = await fetch("https://api.github.com/repos/Andre601/asl-api/releases/latest").then(_ => _.json());
const tag = await fetch(`${url}/api/latest-release`).then(_ => _.json());
const data = {
"version": tag.tag_name
"version": tag.name
};
__md_set("__api_tag", data, sessionStorage);
@@ -57,8 +57,8 @@ document$.subscribe(async () => {
async function fetchInfo() {
const [release, repo] = await Promise.all([
fetch(`${url}/latest-release`).then(_ => _.json()),
fetch(`${url}/stats`).then(_ => _.json()),
fetch(`${url}/repo/latest-release`).then(_ => _.json()),
fetch(`${url}/repo/stats`).then(_ => _.json()),
]);
const data = {
+23
View File
@@ -0,0 +1,23 @@
:root {
--admonition-icon--file: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M3 3a2 2 0 0 1 2-2h9.982a2 2 0 0 1 1.414.586l4.018 4.018A2 2 0 0 1 21 7.018V21a2 2 0 0 1-2 2H4.75a.75.75 0 0 1 0-1.5H19a.5.5 0 0 0 .5-.5V8.5h-4a2 2 0 0 1-2-2v-4H5a.5.5 0 0 0-.5.5v6.25a.75.75 0 0 1-1.5 0Zm12-.5v4a.5.5 0 0 0 .5.5h4a.5.5 0 0 0-.146-.336l-4.018-4.018A.5.5 0 0 0 15 2.5Z"></path><path d="M4.53 12.24a.75.75 0 0 1-.039 1.06l-2.639 2.45 2.64 2.45a.75.75 0 1 1-1.022 1.1l-3.23-3a.75.75 0 0 1 0-1.1l3.23-3a.75.75 0 0 1 1.06.04Zm3.979 1.06a.75.75 0 1 1 1.02-1.1l3.231 3a.75.75 0 0 1 0 1.1l-3.23 3a.75.75 0 1 1-1.021-1.1l2.639-2.45-2.64-2.45Z"></path></svg>');
--admonition-color-fg--file: #00c853;
--admonition-color-bg--file: #00c8531a;
}
.md-typeset .admonition.file,
.md-typeset details.file {
border-color: var(--admonition-color-fg--file);
}
.md-typeset .file > .admonition-title,
.md-typeset .file > summary {
background-color: var(--admonition-color-bg--file);
}
.md-typeset .file > .admonition-title::before,
.md-typeset .file > summary::before {
background-color: var(--admonition-color-fg--file);
-webkit-mask-image: var(--admonition-icon--file);
mask-image: var(--admonition-icon--file);
}
+28 -11
View File
@@ -5,7 +5,7 @@ icon: octicons/milestone-24
# Getting Started
This page will explain how to set up AdvancedServerList and make it work for your server.
It tries to be an easy to understand as possible. But if you still have problems, consider joining the [Discord Server](https://discord.gg/6dazXp6) for help.
It tries to be as easy to understand as possible. But if you still have problems, consider joining the [Discord Server](https://discord.gg/6dazXp6) for help.
## 1. Download the plugin { #download-the-plugin }
@@ -130,6 +130,8 @@ The profiles folder is home of the server list profile files which allow you to
On first creation will the folder have a `default.yml` file. This file contains all the options available to use alongside comments to try and help you in using it properly.
/// details | default.yml content
type: file
```yaml
#
# Set the priority of this profile.
@@ -310,12 +312,15 @@ These functions include, but aren't limited to:
- Disabling/Enabling caching of players.
- Disabling/Enabling checking for updates.
- Disabling/Enabling debug mode.
- Setting how long favicons should be cached for.
- The config version used for migration. Don't touch this, or it may reset your config.
Similar to the default.yml is this file containing comments to try and explain the settings in questions.
Do note that if the config gets migrated from an older version, that the comments will be discarded in the process, unfortunately.
/// details | default config.yml content
type: file
```yaml
#
# Used for when AdvancedServerList doesn't have a cached player to use for player placeholders.
@@ -361,13 +366,21 @@ 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!
#
# This is used internally to determine if the config needs to be migrated.
# Changing or even removing this option could result in your config being broken.
#
config-version: 2
config-version: 4
```
///
@@ -375,18 +388,22 @@ 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
- A `playercache.json` file will be created on plugin shutdown containing a collection of IPs, UUIDs and Player names for every player that joined the server while AdvancedServerList was running.
This file is used to identify a player through their last used IP, to replace placeholders such as `${player name}` or `${player uuid}` with their respective values using the cached data.
This file is not created, used 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.
Each backup will have the name pattern `config-<date>.yml` with `<date>` being the date and time of when this file has been created.
## 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 [condition](../profiles/index.md#condition)) support [MiniMessage formatting](../profiles/formatting.md).
It's best to open the `default.yml` file located inside `profiles` with the file editor of your choice ([:simple-vscodium: VSCodeium](https://vscodium.com/) or [:simple-notepadplusplus: Notepad++](https://notepad-plus-plus.org/) are recommended).
This file should contain all available options that you can set and alter.
Edit the options to whatever you like. All text-based options, except [`condition`](../profiles/index.md#condition), support [MiniMessage formatting](../profiles/formatting.md).
The [`motd`](../profiles/index.md#motd) option also supports Hexadecimal colors, assuming the server/proxy runs at least MC 1.16.
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.
@@ -402,7 +419,7 @@ motd:
### Additional profiles
To add additional profiles, create a new YAML file inside the `profiles` folder. The name doesn't matter, but it is recommended to keep it lowercase, use alphanumeric characters (`a-z, 0-9`), hyphens (`-`), underscores (`_`) and avoid spaces.
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. You should also name it after what it is for, to have it more easily organized.
Inside the file, add a priority and at least one setting, similar to the above shown example.
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.
@@ -411,7 +428,7 @@ If you want to only show this file under specific situations can you use the [`c
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.
/// 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.
Profiles which do not have any conditions, or have an empty condition, will always be 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:
@@ -431,7 +448,7 @@ The [Examples page](../examples/index.md) contains more examples of different se
## 4. Loading profiles { #loading-profiles }
Once you've set up your server list profile(s) is it time to load it/them.
To do this, simply run `/asl reload` as player (Requires permission `advancedserverlist.admin` or `advancedserverlist.command.reload`) or through the Server/Proxy console.
To do this, simply run `/asl reload` as player (Requires permission `advancedserverlist.admin` or `advancedserverlist.command.reload`) or `asl reload` through the Server/Proxy console.
The plugin should then load any valid YAML file inside the `profiles` folder to then use.
+1
View File
@@ -51,6 +51,7 @@ extra_css:
- assets/stylesheets/custom.css
- assets/stylesheets/api-docs.css
- assets/stylesheets/admo.css
- assets/stylesheets/admonition.css
extra_javascript:
- assets/js/repo-stats.js
@@ -178,7 +178,7 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
@Override
public PaperPlayerImpl createPlayer(CachedPlayer player, int protocol){
OfflinePlayer pl = Bukkit.getOfflinePlayer(player.getUuid());
OfflinePlayer pl = Bukkit.getOfflinePlayer(player.uuid());
return new PaperPlayerImpl(pl.hasPlayedBefore() ? pl : null, player, protocol);
}
@@ -40,9 +40,9 @@ public class PaperPlayerImpl extends GenericPlayerImpl implements BukkitPlayer{
public PaperPlayerImpl(OfflinePlayer player, CachedPlayer cachedPlayer, int protocol){
this.player = player;
this.name = player == null ? cachedPlayer.getName() : player.getName();
this.name = player == null ? cachedPlayer.name() : player.getName();
this.protocol = protocol;
this.uuid = player == null ? cachedPlayer.getUuid() : player.getUniqueId();
this.uuid = player == null ? cachedPlayer.uuid() : player.getUniqueId();
if(player == null)
return;
+6 -2
View File
@@ -38,10 +38,10 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.commit/>
<plugin.version>4.1.0</plugin.version>
<plugin.version>4.3.0</plugin.version>
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
<api.version>v3.1.0</api.version>
<api.version>3.2.1</api.version>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
@@ -52,6 +52,10 @@
<id>jitpack</id>
<url>https://jitpack.io/</url>
</repository>
<repository>
<id>codeberg</id>
<url>https://codeberg.org/api/packages/Andre601/maven/</url>
</repository>
</repositories>
<modules>
+15 -5
View File
@@ -7,18 +7,28 @@
],
"packageRules": [
{
"description": "Use a specific registry URL for specific dependencies",
"description": "Use Jitpack registry for AdvancedBan",
"matchPackageNames": [
"ch.andre601.asl-api:platform-bukkit",
"ch.andre601.asl-api:platform-bungeecord",
"ch.andre601.asl-api:platform-velocity",
"ch.andre601.asl-api:api",
"com.github.DevLeoko:AdvancedBan"
],
"registryUrls": [
"https://jitpack.io"
]
},
{
"description": "Use Codeberg packages for asl-api",
"matchPackageNames": [
"ch.andre601.asl-api:api",
"ch.andre601.asl-api:parent",
"ch.andre601.asl-api:platform-bukkit",
"ch.andre601.asl-api:platform-bungeecord",
"ch.andre601.asl-api:platform-velocity",
"ch.andre601:ExpressionParser"
],
"registryUrls": [
"https://codeberg.org/api/packages/Andre601/maven"
]
},
{
"description": "Apply label for Bukkit platform",
"matchFileNames": ["bukkit/pom.xml"],
+1 -1
View File
@@ -1,4 +1,4 @@
mkdocs-material==9.5.10
mkdocs-material==9.5.12
mkdocs-glightbox==0.3.7
mkdocs-awesome-pages-plugin==2.9.2
git+https://github.com/Andre601/mkdocs-pagenav-generator
@@ -33,8 +33,8 @@ import ch.andre601.advancedserverlist.velocity.commands.CmdAdvancedServerList;
import ch.andre601.advancedserverlist.velocity.listeners.JoinEvent;
import ch.andre601.advancedserverlist.velocity.listeners.PingEvent;
import ch.andre601.advancedserverlist.velocity.logging.VelocityLogger;
import ch.andre601.advancedserverlist.velocity.objects.VelocityPlayerPlaceholders;
import ch.andre601.advancedserverlist.velocity.objects.VelocityServerPlaceholders;
import ch.andre601.advancedserverlist.velocity.objects.placeholders.VelocityPlayerPlaceholders;
import ch.andre601.advancedserverlist.velocity.objects.placeholders.VelocityServerPlaceholders;
import com.google.inject.Inject;
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.event.Subscribe;
@@ -35,8 +35,8 @@ import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.velocity.VelocityCore;
import ch.andre601.advancedserverlist.velocity.objects.VelocityPlayerImpl;
import ch.andre601.advancedserverlist.velocity.objects.VelocityProxyImpl;
import ch.andre601.advancedserverlist.velocity.objects.impl.VelocityPlayerImpl;
import ch.andre601.advancedserverlist.velocity.objects.impl.VelocityProxyImpl;
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,7 @@
*
*/
package ch.andre601.advancedserverlist.velocity.objects;
package ch.andre601.advancedserverlist.velocity.objects.impl;
import ch.andre601.advancedserverlist.api.velocity.objects.VelocityPlayer;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
@@ -35,9 +35,9 @@ public class VelocityPlayerImpl extends GenericPlayerImpl implements VelocityPla
private final String version;
public VelocityPlayerImpl(CachedPlayer player, int protocol){
this.name = player.getName();
this.name = player.name();
this.protocol = protocol;
this.uuid = player.getUuid();
this.uuid = player.uuid();
this.version = ProtocolVersion.getProtocolVersion(protocol).getVersionIntroducedIn();
}
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,7 @@
*
*/
package ch.andre601.advancedserverlist.velocity.objects;
package ch.andre601.advancedserverlist.velocity.objects.impl;
import ch.andre601.advancedserverlist.api.velocity.objects.VelocityProxy;
import com.velocitypowered.api.proxy.server.RegisteredServer;
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,7 @@
*
*/
package ch.andre601.advancedserverlist.velocity.objects;
package ch.andre601.advancedserverlist.velocity.objects.placeholders;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
@@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
* Copyright (c) 2022-2024 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,7 @@
*
*/
package ch.andre601.advancedserverlist.velocity.objects;
package ch.andre601.advancedserverlist.velocity.objects.placeholders;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
+2 -2
View File
@@ -52,7 +52,7 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.0</version>
<version>1.5.1</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -76,7 +76,7 @@
<dependency>
<groupId>club.minnced</groupId>
<artifactId>discord-webhooks</artifactId>
<version>0.8.2</version>
<version>0.8.4</version>
<scope>compile</scope>
</dependency>
</dependencies>
@@ -48,7 +48,8 @@ public enum PlatformInfo{
VELOCITY(
"velocity",
List.of(
"velocity/target/AdvancedServerList-Velocity-{{version}}.jar"
"velocity/target/AdvancedServerList-Velocity-{{version}}.jar",
"addons/banplugins/target/AdvancedServerList-BanPlugins-Addon-{{version}}.jar"
),
"velocity"
);