mirror of
https://codeberg.org/Andre601/AdvancedServerList.git
synced 2026-11-05 09:00:15 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35120c5364 | ||
|
|
6c828171d2 | ||
|
|
dcc51f8458 | ||
|
|
1287ca62fe | ||
|
|
1ff439fa95 | ||
|
|
ed0f832b2f | ||
|
|
b8e6b2acc6 | ||
|
|
fba32c91c5 | ||
|
|
6505ded12b | ||
|
|
53088affcb | ||
|
|
9c030764fa | ||
|
|
d5d58f1eea | ||
|
|
7181092821 | ||
|
|
fc5ee4f242 | ||
|
|
6e74c4fb14 | ||
|
|
f6a27342e6 | ||
|
|
38b50df2c9 | ||
|
|
db93816e55 | ||
|
|
244c2440fc | ||
|
|
8e2c644669 | ||
|
|
a68809ab31 | ||
|
|
4b4fd80abe | ||
|
|
48ea128267 | ||
|
|
68e5795618 | ||
|
|
1aa20e4196 | ||
|
|
6db25c8f9c | ||
|
|
0ef3db752d | ||
|
|
1a26f5ad34 | ||
|
|
17a5574be7 | ||
|
|
c7bfb8a736 | ||
|
|
7a756c3b98 | ||
|
|
1539e1c3c0 | ||
|
|
a86872c021 | ||
|
|
7d12499f39 | ||
|
|
455434b5f3 | ||
|
|
b66251ab20 | ||
|
|
4a1dfa5cb4 | ||
|
|
1efd65e16c | ||
|
|
908da9cd32 | ||
|
|
e8a30c6ef7 | ||
|
|
df164c104f | ||
|
|
acdf6f6e9a | ||
|
|
f52a63a8f1 | ||
|
|
6a92cb3a16 | ||
|
|
1175451753 | ||
|
|
5c4130411b | ||
|
|
05727eeec5 | ||
|
|
10af949abc | ||
|
|
9851347e74 | ||
|
|
c3e01c8b9c | ||
|
|
a646d9e998 | ||
|
|
3c50a30d4a | ||
|
|
4328ad6b44 | ||
|
|
34b0555508 | ||
|
|
c92cd0058b | ||
|
|
2cfe8b8a27 | ||
|
|
6530fed704 | ||
|
|
7efb203e7b | ||
|
|
1a34376100 | ||
|
|
ec1aa5b393 | ||
|
|
9683d3c001 | ||
|
|
db60545fcc | ||
|
|
392495ef63 | ||
|
|
903764b234 | ||
|
|
72329ed1e4 | ||
|
|
c516b56053 | ||
|
|
5e4295fbfb | ||
|
|
b140c0aa32 | ||
|
|
8f7b293541 | ||
|
|
6f878164c5 | ||
|
|
a16801ff56 | ||
|
|
65a89cf762 | ||
|
|
27d4ada179 | ||
|
|
574edfb246 | ||
|
|
7b7aad9d4e | ||
|
|
c5c9ed8109 | ||
|
|
58fea4090d | ||
|
|
cd0aad6ec1 | ||
|
|
fa45844434 | ||
|
|
c4e2a144b5 | ||
|
|
7fe93c7021 | ||
|
|
1d413a5c2a | ||
|
|
51db52dbdd | ||
|
|
4ade528188 | ||
|
|
64ba48a7c7 | ||
|
|
ac4edb2b97 | ||
|
|
3ea000c98b | ||
|
|
746bef13e1 | ||
|
|
355ab73546 | ||
|
|
67170c70e0 | ||
|
|
f99c2df4e8 | ||
|
|
212ec04fb8 | ||
|
|
89c6089101 | ||
|
|
87bce39d9a | ||
|
|
18900547a0 | ||
|
|
5df2e05a14 | ||
|
|
d4e4173cc3 | ||
|
|
562ad481c5 | ||
|
|
a0ee2a4322 | ||
|
|
2c92efdb43 | ||
|
|
555dc9d6a5 | ||
|
|
27742c5e1b | ||
|
|
280aeb8d2e | ||
|
|
92a868f0fa | ||
|
|
189ac5e09b | ||
|
|
833cb81d65 | ||
|
|
ab09422da5 | ||
|
|
64cad6dc26 | ||
|
|
ce78b493f4 | ||
|
|
c43048ea3f | ||
|
|
6d4d1600ab | ||
|
|
f114e99b9b | ||
|
|
3d587bc86d | ||
|
|
bd8c6be7c6 | ||
|
|
b5d5d508e2 | ||
|
|
3001b65fe8 | ||
|
|
c82771db59 | ||
|
|
9880836c25 | ||
|
|
f12ae28722 | ||
|
|
42b0f0e94f | ||
|
|
0a4b872051 | ||
|
|
b1322105ed | ||
|
|
831ca57fbb | ||
|
|
6502639cd3 | ||
|
|
5059b80db2 | ||
|
|
ecdaf72963 | ||
|
|
28e2ca69ed | ||
|
|
9cad78b6e4 | ||
|
|
af8654666b | ||
|
|
6cd474b35d | ||
|
|
3802ab556c | ||
|
|
3a520eeaf0 | ||
|
|
204f43c112 | ||
|
|
fc8ed8e49e | ||
|
|
56082c308b | ||
|
|
205e563095 | ||
|
|
5b01940c60 | ||
|
|
cbb087e3d1 | ||
|
|
524b926244 | ||
|
|
4059bbfe93 | ||
|
|
9b0b69a4f4 | ||
|
|
10a82eb951 | ||
|
|
690f7dfaf0 | ||
|
|
6a22d20b3a | ||
|
|
b1072bb1fa | ||
|
|
d20da91bab | ||
|
|
17e9692028 | ||
|
|
45dc8a5fe6 | ||
|
|
a237ac1ce4 | ||
|
|
27e66a16b9 |
No files matched your search
@@ -24,11 +24,11 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python 3.7
|
||||
uses: actions/setup-python@v4
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Create/Get Cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
key: ${{ github.ref }}
|
||||
path: .cache
|
||||
@@ -39,11 +39,11 @@ jobs:
|
||||
- name: Build docs
|
||||
run: mkdocs build
|
||||
- name: Configure GitHub Pages
|
||||
uses: actions/configure-pages@v3
|
||||
uses: actions/configure-pages@v4
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v2
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: 'site/'
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v2
|
||||
uses: actions/deploy-pages@v4
|
||||
@@ -4,12 +4,10 @@ when:
|
||||
|
||||
steps:
|
||||
createFiles:
|
||||
image: maven:3.9.4-eclipse-temurin-17
|
||||
image: maven:3.9.6-eclipse-temurin-17
|
||||
secrets:
|
||||
- source: cb_token
|
||||
target: codeberg_api_token
|
||||
- source: gh_token
|
||||
target: github_api_token
|
||||
- source: modrinth_api_token
|
||||
target: modrinth_api_token
|
||||
- source: hangar_api_token
|
||||
@@ -22,14 +20,14 @@ steps:
|
||||
- mv VersionUploader.jar ../../
|
||||
- cd ../../
|
||||
# Execute Jar file
|
||||
- java -jar VersionUploader.jar --all
|
||||
- java -jar VersionUploader.jar --modrinth
|
||||
uploadToCodeberg:
|
||||
image: woodpeckerci/plugin-gitea-release
|
||||
settings:
|
||||
base_url: https://codeberg.org
|
||||
files:
|
||||
- "bukkit/target/AdvancedServerList-*.jar"
|
||||
- "bungeecord/target/AdvancedServerList-*.jar"
|
||||
- "paper/target/AdvancedServerList-*.jar"
|
||||
- "velocity/target/AdvancedServerList-*.jar"
|
||||
api_key:
|
||||
from_secret: CB_TOKEN
|
||||
@@ -4,25 +4,33 @@ when:
|
||||
path:
|
||||
include: ['requirements.txt', 'mkdocs.yml', 'docs/**']
|
||||
|
||||
variables:
|
||||
setup_git: &setup_git
|
||||
- apk add git
|
||||
- git config --global user.email "github@andre601.ch"
|
||||
- git config --global user.name "ASL Docs Builder"
|
||||
|
||||
steps:
|
||||
cloneTargetRepo:
|
||||
image: alpine:3.18.4
|
||||
commands:
|
||||
- chmod -R a+w .
|
||||
- <<: *setup_git
|
||||
- git clone -b pages https://codeberg.org/Andre601/AdvancedServerList.git site
|
||||
- chmod -R a+w site
|
||||
buildDocs:
|
||||
image: python
|
||||
image: woodpeckerci/plugin-mkdocs:latest
|
||||
settings:
|
||||
pip_install_file: requirements.txt
|
||||
commitAndPush:
|
||||
image: alpine:3.18.4
|
||||
secrets:
|
||||
- cb_token
|
||||
commands:
|
||||
- chmod -R a+w .
|
||||
- git config --global --add safe.directory /woodpecker/src/codeberg.org/Andre601/blog-source/website
|
||||
- git config --global user.email "github@andre601.ch"
|
||||
- git config --global user.name "CI Website Builder"
|
||||
- git fetch --unshallow
|
||||
- git clone -b pages https://codeberg.org/Andre601/AdvancedServerList.git site
|
||||
- chmod -R a+w site
|
||||
- python -m pip install --upgrade pip
|
||||
- python -m pip install -r requirements.txt
|
||||
- mkdocs build
|
||||
- <<: *setup_git
|
||||
- mv domains site/.domains
|
||||
- cd site
|
||||
- git remote set-url origin https://$CB_TOKEN@codeberg.org/Andre601/AdvancedServerList.git
|
||||
- git add --all
|
||||
- git commit -m "Update AdvancedServerList Docs ($( env TZ=Europe/Zurich date +"%d.%m.%Y" )) [CI SKIP]"
|
||||
- git commit -m "Update AdvancedServerList Docs ($( env TZ=Europe/Zurich date +"%d.%m.%Y %Z" )) [SKIP CI]"
|
||||
- git push
|
||||
@@ -8,15 +8,14 @@ AdvancedServerList is a plugin that allowys you to customize your server's MOTD,
|
||||
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact/available/modrinth_vector.svg" height="46" alt="modrinth" title="Available on Modrinth">
|
||||
</a>
|
||||
<br>
|
||||
<!--
|
||||
<a href="https://hangar.papermc.io/Andre_601/AdvancedServerList" target="_blank">
|
||||
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact/available/hangar_vector.svg" height="46" alt="hangar" title="Available on Hangar">
|
||||
</a>
|
||||
-->
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
<a href="https://www.spigotmc.org" target="_blank">
|
||||
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/supported/spigot_vector.svg" height="64" alt="platform-spigot" title="Tested on Spigot">
|
||||
</a>
|
||||
<a href="https://papermc.io" target="_blank">
|
||||
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/supported/paper_vector.svg" height="64" alt="platform-paper" title="Tested on Paper">
|
||||
</a>
|
||||
@@ -61,13 +60,14 @@ Only certain options are usable for each option. As an example does motd support
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Dependency | Platforms | Required? |
|
||||
|-------------------|----------------------|-----------|
|
||||
| [ProtocolLib] | Spigot | Yes |
|
||||
| [PlaceholderAPI] | Spigot, Paper | No |
|
||||
| [ViaVersion] | Spigot, Paper | No |
|
||||
| [PAPIProxyBridge] | BungeeCord, Velocity | No |
|
||||
| [Maintenance] | All | No |
|
||||
All listed dependencies are optional.
|
||||
|
||||
| Dependency | Platforms |
|
||||
|-------------------|----------------------|
|
||||
| [PlaceholderAPI] | Paper |
|
||||
| [ViaVersion] | Paper |
|
||||
| [PAPIProxyBridge] | BungeeCord, Velocity |
|
||||
| [Maintenance] | All |
|
||||
|
||||
## Statistics
|
||||
|
||||
@@ -98,13 +98,12 @@ You can disable this in the global bStats config file located in `/plugins/bstat
|
||||
|
||||
<!-- Links -->
|
||||
[profiles]: https://asl.andre601.ch/profiles/
|
||||
[conditions]: https://asl.andre601.ch/profiles/#conditions
|
||||
[conditions]: https://asl.andre601.ch/profiles/#condition
|
||||
[placeholders]: https://asl.andre601.ch/profiles/placeholders/
|
||||
[minimessage]: https://asl.andre601.ch/profiles/formatting/
|
||||
|
||||
[modrinth]: https://modrinth.com/plugin/advancedserverlist
|
||||
|
||||
[protocollib]: https://hangar.papermc.io/dmulloy2/ProtocolLib
|
||||
[placeholderapi]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
|
||||
[viaversion]: https://hangar.papermc.io/ViaVersion/ViaVersion
|
||||
[papiproxybridge]: https://hangar.papermc.io/William278/PAPIProxyBridge
|
||||
|
||||
-75
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.bukkit.commands;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.commands.CmdSender;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.paper.commands.PaperCmdSender;
|
||||
import ch.andre601.advancedserverlist.spigot.commands.SpigotCmdSender;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class CmdAdvancedServerList extends Command implements CommandExecutor{
|
||||
|
||||
private final PluginCore<?> plugin;
|
||||
private final BukkitAudiences audiences;
|
||||
|
||||
public CmdAdvancedServerList(PluginCore<?> plugin){
|
||||
this(plugin, null);
|
||||
}
|
||||
|
||||
public CmdAdvancedServerList(PluginCore<?> plugin, BukkitAudiences audiences){
|
||||
super(
|
||||
"advancedserverlist",
|
||||
"Main command of the plugin",
|
||||
"/asl [reload|help|clearCache]",
|
||||
Collections.singletonList("asl")
|
||||
);
|
||||
|
||||
this.plugin = plugin;
|
||||
this.audiences = audiences;
|
||||
}
|
||||
|
||||
public boolean execute(@NotNull CommandSender sender, @NotNull String s, @NotNull String[] args){
|
||||
plugin.getCore().getCommandHandler().handle(getSender(sender), args);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, @NotNull String[] args){
|
||||
plugin.getCore().getCommandHandler().handle(getSender(sender), args);
|
||||
return true;
|
||||
}
|
||||
|
||||
private CmdSender getSender(CommandSender sender){
|
||||
return audiences == null ? new PaperCmdSender(sender) : new SpigotCmdSender(sender, audiences);
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.bukkit.listeners;
|
||||
|
||||
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
|
||||
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.PAPIPlaceholders;
|
||||
import ch.andre601.advancedserverlist.spigot.SpigotCore;
|
||||
import ch.andre601.advancedserverlist.spigot.listeners.ProtocolLibEvents;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.ServerLoadEvent;
|
||||
|
||||
public class LoadEvent implements Listener{
|
||||
|
||||
private final BukkitCore<?> plugin;
|
||||
|
||||
private LoadEvent(BukkitCore<?> plugin){
|
||||
this.plugin = plugin;
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
public static void init(BukkitCore<?> plugin){
|
||||
new LoadEvent(plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onServerLoad(ServerLoadEvent event){
|
||||
JoinEvent.init(plugin);
|
||||
WorldEvents.init(plugin);
|
||||
|
||||
// Populate WorldCache with all loaded worlds
|
||||
Bukkit.getWorlds().forEach(world -> plugin.getWorldCache().addWorld(world.getName(), world));
|
||||
|
||||
if(!(plugin instanceof SpigotCore spigotCore))
|
||||
return;
|
||||
|
||||
if(!Bukkit.getPluginManager().isPluginEnabled("ProtocolLib")){
|
||||
plugin.getCore().getPlugin().getPluginLogger().warn("ProtocolLib not found! AdvancedServerList requires it to work on Spigot!");
|
||||
|
||||
Bukkit.getPluginManager().disablePlugin(plugin);
|
||||
return;
|
||||
}
|
||||
|
||||
ProtocolLibEvents.init(spigotCore, ProtocolLibrary.getProtocolManager());
|
||||
|
||||
if(Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
spigotCore.setPapiPlaceholders(PAPIPlaceholders.init(spigotCore));
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.paper;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import io.papermc.paper.plugin.loader.PluginClasspathBuilder;
|
||||
import io.papermc.paper.plugin.loader.PluginLoader;
|
||||
import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||
import org.eclipse.aether.artifact.DefaultArtifact;
|
||||
import org.eclipse.aether.graph.Dependency;
|
||||
import org.eclipse.aether.repository.RemoteRepository;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ASLLoader implements PluginLoader{
|
||||
@Override
|
||||
public void classloader(@NotNull PluginClasspathBuilder pluginClasspathBuilder){
|
||||
ComponentLogger logger = pluginClasspathBuilder.getContext().getLogger();
|
||||
|
||||
logger.info(Component.text("Loading Libraries for plugin..."));
|
||||
|
||||
MavenLibraryResolver resolver = new MavenLibraryResolver();
|
||||
|
||||
resolver.addRepository(new RemoteRepository.Builder(
|
||||
"paper-maven",
|
||||
"default",
|
||||
"https://repo.papermc.io/repository/maven-public/"
|
||||
).build());
|
||||
|
||||
logger.info(Component.text("Loading com.squareup.okhttp3:okhttp:4.10.0 from repo.papermc.io..."));
|
||||
|
||||
resolver.addDependency(new Dependency(new DefaultArtifact("com.squareup.okhttp3:okhttp:4.10.0"), null));
|
||||
pluginClasspathBuilder.addLibrary(resolver);
|
||||
|
||||
logger.info(Component.text("Loading libraries complete!"));
|
||||
}
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot;
|
||||
|
||||
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
|
||||
import ch.andre601.advancedserverlist.bukkit.commands.CmdAdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.bukkit.logging.BukkitLogger;
|
||||
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.BukkitPlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.BukkitServerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.PAPIPlaceholders;
|
||||
import ch.andre601.advancedserverlist.bukkit.objects.WorldCache;
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
|
||||
import ch.andre601.advancedserverlist.bukkit.listeners.LoadEvent;
|
||||
import com.comphenix.protocol.wrappers.WrappedServerPing;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class SpigotCore extends BukkitCore<WrappedServerPing.CompressedImage>{
|
||||
|
||||
private final PluginLogger logger = new BukkitLogger(getLogger());
|
||||
|
||||
private AdvancedServerList<WrappedServerPing.CompressedImage> core;
|
||||
private FaviconHandler<WrappedServerPing.CompressedImage> faviconHandler = null;
|
||||
private PAPIPlaceholders<WrappedServerPing.CompressedImage> papiPlaceholders = null;
|
||||
private WorldCache worldCache = null;
|
||||
|
||||
@Override
|
||||
public void onEnable(){
|
||||
try{
|
||||
Class.forName("io.papermc.paper.configuration.ConfigurationLoaders");
|
||||
|
||||
printPaperInfo();
|
||||
}catch(ClassNotFoundException ex){
|
||||
try{
|
||||
// Above class only exists since 1.19+, so this is a fallback for older versions.
|
||||
Class.forName("com.destroystokyo.paper.PaperConfig");
|
||||
|
||||
printPaperInfo();
|
||||
}catch(ClassNotFoundException ignored){}
|
||||
}
|
||||
|
||||
this.core = AdvancedServerList.init(this, BukkitPlayerPlaceholders.init(), BukkitServerPlaceholders.init());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable(){
|
||||
if(papiPlaceholders != null){
|
||||
papiPlaceholders.unregister();
|
||||
papiPlaceholders = null;
|
||||
}
|
||||
|
||||
if(worldCache != null)
|
||||
worldCache = null;
|
||||
|
||||
getCore().disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCommands(){
|
||||
PluginCommand cmd = getServer().getPluginCommand("advancedserverlist");
|
||||
if(cmd == null){
|
||||
getPluginLogger().warn("Unable to register command /advancedserverlist");
|
||||
return;
|
||||
}
|
||||
cmd.setExecutor(new CmdAdvancedServerList(this, BukkitAudiences.create(this)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadEvents(){
|
||||
LoadEvent.init(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadMetrics(){
|
||||
new Metrics(this, 15584).addCustomChart(new SimplePie("profiles",
|
||||
() -> String.valueOf(core.getFileHandler().getProfiles().size())
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearFaviconCache(){
|
||||
if(faviconHandler == null)
|
||||
return;
|
||||
|
||||
faviconHandler.clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdvancedServerList<WrappedServerPing.CompressedImage> getCore(){
|
||||
return core;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getFolderPath(){
|
||||
return getDataFolder().toPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PluginLogger getPluginLogger(){
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaviconHandler<WrappedServerPing.CompressedImage> getFaviconHandler(){
|
||||
if(faviconHandler == null)
|
||||
faviconHandler = new FaviconHandler<>(core);
|
||||
|
||||
return faviconHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatformName(){
|
||||
return getServer().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatformVersion(){
|
||||
return getServer().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLoader(){
|
||||
return "spigot";
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldCache getWorldCache(){
|
||||
if(worldCache != null)
|
||||
return worldCache;
|
||||
|
||||
return (worldCache = new WorldCache());
|
||||
}
|
||||
|
||||
public void setPapiPlaceholders(PAPIPlaceholders<WrappedServerPing.CompressedImage> papiPlaceholders){
|
||||
this.papiPlaceholders = papiPlaceholders;
|
||||
}
|
||||
|
||||
private void printPaperInfo(){
|
||||
getPluginLogger().warn("======================================================================================");
|
||||
getPluginLogger().warn("You are using the Spigot version of AdvancedServerList on a Paper server.");
|
||||
getPluginLogger().warn("It is recommended to use the dedicated Paper version, to benefit from the");
|
||||
getPluginLogger().warn("following improvements:");
|
||||
getPluginLogger().warn(" - No downloading of external Libraries already provided by Paper (i.e. Adventure).");
|
||||
getPluginLogger().warn(" - No dependency on ProtocolLib thanks to provided Events.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("AdvancedServerList may work as normal, but consider using the PaperMC version instead!");
|
||||
getPluginLogger().warn("======================================================================================");
|
||||
}
|
||||
}
|
||||
-203
@@ -1,203 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot.listeners;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
|
||||
import ch.andre601.advancedserverlist.bukkit.listeners.PreServerListSetEventImpl;
|
||||
import ch.andre601.advancedserverlist.bukkit.objects.impl.BukkitServerImpl;
|
||||
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
|
||||
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import ch.andre601.advancedserverlist.spigot.SpigotCore;
|
||||
import ch.andre601.advancedserverlist.bukkit.objects.impl.BukkitPlayerImpl;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import com.comphenix.protocol.wrappers.WrappedServerPing;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.*;
|
||||
|
||||
public class ProtocolLibEventWrapper implements GenericEventWrapper<WrappedServerPing.CompressedImage, BukkitPlayerImpl>{
|
||||
|
||||
private final SpigotCore plugin;
|
||||
private final PacketEvent event;
|
||||
private final WrappedServerPing ping;
|
||||
|
||||
public ProtocolLibEventWrapper(SpigotCore plugin, PacketEvent event){
|
||||
this.plugin = plugin;
|
||||
this.event = event;
|
||||
this.ping = event.getPacket().getServerPings().read(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericServerListEvent callEvent(ProfileEntry entry){
|
||||
PreServerListSetEventImpl event = new PreServerListSetEventImpl(entry);
|
||||
plugin.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxPlayers(int maxPlayers){
|
||||
ping.setPlayersMaximum(maxPlayers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMotd(Component component){
|
||||
ping.setMotD(WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(component)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hidePlayers(){
|
||||
ping.setPlayersVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayerCount(String name){
|
||||
ping.setVersionName(name);
|
||||
ping.setVersionProtocol(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayers(List<String> lines, BukkitPlayerImpl player, GenericServer server){
|
||||
List<WrappedGameProfile> players = new ArrayList<>(lines.size());
|
||||
|
||||
for(String line : lines){
|
||||
String parsed = ComponentParser.text(line)
|
||||
.modifyText(text -> StringReplacer.replace(text, player, server))
|
||||
.modifyText(text -> {
|
||||
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
|
||||
|
||||
return text;
|
||||
})
|
||||
.toString();
|
||||
|
||||
players.add(new WrappedGameProfile(UUID.randomUUID(), parsed));
|
||||
}
|
||||
|
||||
ping.setPlayers(players);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFavicon(WrappedServerPing.CompressedImage favicon){
|
||||
ping.setFavicon(favicon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultFavicon(){
|
||||
ping.setFavicon(ping.getFavicon());
|
||||
}
|
||||
|
||||
// Not used in ProtocolLib
|
||||
@Override
|
||||
public void updateEvent(){
|
||||
event.getPacket().getServerPings().write(0, ping);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInvalidProtocol(){
|
||||
return event.getPlayer().getAddress() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMaintenanceModeActive(){
|
||||
if(!Bukkit.getPluginManager().isPluginEnabled("Maintenance"))
|
||||
return false;
|
||||
|
||||
return PingEventHandler.getMaintenanceUtil().isMaintenanceEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtocolVersion(){
|
||||
return ping.getVersionProtocol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOnlinePlayers(){
|
||||
return ping.getPlayersOnline();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxPlayers(){
|
||||
return ping.getPlayersMaximum();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlayerIP(){
|
||||
return event.getPlayer().getAddress() == null ? "UNKNOWN" : event.getPlayer().getAddress().getHostString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parsePAPIPlaceholders(String text, BukkitPlayerImpl player){
|
||||
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVirtualHost(){
|
||||
String host = this.resolveHost(event.getPlayer().getAddress());
|
||||
if(host == null)
|
||||
return null;
|
||||
|
||||
return ProtocolLibEvents.getHostAddresses().get(host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitCore<WrappedServerPing.CompressedImage> getPlugin(){
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitPlayerImpl createPlayer(CachedPlayer player, int protocol){
|
||||
OfflinePlayer pl = Bukkit.getOfflinePlayer(player.getUuid());
|
||||
|
||||
return new BukkitPlayerImpl(pl.hasPlayedBefore() ? pl : null, player, protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericServer createGenericServer(int playersOnline, int playersMax, String host){
|
||||
return new BukkitServerImpl(plugin.getWorldCache().worlds(), playersOnline, playersMax, host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WrappedServerPing.CompressedImage createFavicon(BufferedImage image) throws Exception{
|
||||
return WrappedServerPing.CompressedImage.fromPng(image);
|
||||
}
|
||||
}
|
||||
-84
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot.listeners;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
|
||||
import ch.andre601.advancedserverlist.spigot.SpigotCore;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class ProtocolLibEvents implements Listener{
|
||||
|
||||
private final ProtocolManager protocolManager;
|
||||
|
||||
private static final Map<String, String> hostAddresses = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
private ProtocolLibEvents(SpigotCore plugin, ProtocolManager protocolManager){
|
||||
this.protocolManager = protocolManager;
|
||||
|
||||
loadPacketListener(plugin);
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
public static void init(SpigotCore plugin, ProtocolManager protocolManager){
|
||||
new ProtocolLibEvents(plugin, protocolManager);
|
||||
}
|
||||
|
||||
public static Map<String, String> getHostAddresses(){
|
||||
return hostAddresses;
|
||||
}
|
||||
|
||||
private void loadPacketListener(SpigotCore spigotPlugin){
|
||||
protocolManager.addPacketListener(new PacketAdapter(spigotPlugin, ListenerPriority.LOW, PacketType.Handshake.Client.SET_PROTOCOL){
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event){
|
||||
InetSocketAddress address = event.getPlayer().getAddress();
|
||||
if(address == null)
|
||||
return;
|
||||
|
||||
String host = event.getPacket().getStrings().read(0);
|
||||
|
||||
hostAddresses.put(address.getHostString(), host);
|
||||
}
|
||||
});
|
||||
|
||||
protocolManager.addPacketListener(new PacketAdapter(spigotPlugin, ListenerPriority.LOW, PacketType.Status.Server.SERVER_INFO){
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event){
|
||||
PingEventHandler.handleEvent(new ProtocolLibEventWrapper(spigotPlugin, event));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+6
-16
@@ -67,33 +67,33 @@
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.20-R0.1</version>
|
||||
<version>1.20-R0.2</version>
|
||||
<type>jar</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.20-R0.1</version>
|
||||
<version>1.20-R0.2</version>
|
||||
<type>javadoc</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-api</artifactId>
|
||||
<version>4.14.0</version>
|
||||
<version>4.15.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-text-minimessage</artifactId>
|
||||
<version>4.14.0</version>
|
||||
<version>4.15.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-platform-bungeecord</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<version>4.3.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -108,12 +108,6 @@
|
||||
<version>4.1.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>4.11.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -128,7 +122,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<version>3.12.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -149,10 +143,6 @@
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.bstats</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>okhttp3</pattern>
|
||||
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.okhttp3</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<filters>
|
||||
<filter>
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
|
||||
|
||||
private AdvancedServerList<Favicon> core;
|
||||
private FaviconHandler<Favicon> faviconHandler = null;
|
||||
private final PluginLogger logger = new BungeeLogger(getLogger());
|
||||
private final PluginLogger logger = new BungeeLogger(this);
|
||||
|
||||
@Override
|
||||
public void onEnable(){
|
||||
|
||||
+17
-2
@@ -25,6 +25,7 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.bungeecord.logging;
|
||||
|
||||
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
|
||||
import java.util.logging.Level;
|
||||
@@ -32,10 +33,24 @@ import java.util.logging.Logger;
|
||||
|
||||
public class BungeeLogger implements PluginLogger{
|
||||
|
||||
private final BungeeCordCore plugin;
|
||||
private final Logger logger;
|
||||
|
||||
public BungeeLogger(Logger logger){
|
||||
this.logger = logger;
|
||||
public BungeeLogger(BungeeCordCore plugin){
|
||||
this.plugin = plugin;
|
||||
this.logger = plugin.getLogger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(Class<?> clazz, String msg, Object... args){
|
||||
if(plugin.isDebugEnabled())
|
||||
info("[DEBUG] [" + clazz.getSimpleName() + "] " + msg, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debugWarn(Class<?> clazz, String msg, Object... args){
|
||||
if(plugin.isDebugEnabled())
|
||||
warn("[DEBUG] [" + clazz.getSimpleName() + "] " + msg, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+9
-3
@@ -53,10 +53,14 @@ public class BungeeServerPlaceholders extends PlaceholderProvider{
|
||||
return switch(args[0]){
|
||||
case "playersOnline" -> {
|
||||
if(args.length >= 2){
|
||||
int players = 0;
|
||||
String[] servers = args[1].split(",");
|
||||
|
||||
for(int i = 1; i < args.length; i++){
|
||||
ServerInfo info = proxy.getServers().get(args[i]);
|
||||
int players = 0;
|
||||
for(String serverName : servers){
|
||||
if(serverName.isEmpty())
|
||||
continue;
|
||||
|
||||
ServerInfo info = proxy.getServers().get(serverName.strip());
|
||||
if(info == null)
|
||||
continue;
|
||||
|
||||
@@ -81,6 +85,8 @@ public class BungeeServerPlaceholders extends PlaceholderProvider{
|
||||
|
||||
if(args.length == 2){
|
||||
ServerInfo info = proxy.getServers().get(args[1]);
|
||||
if(info == null)
|
||||
yield null;
|
||||
|
||||
yield String.valueOf(((InetSocketAddress)info.getSocketAddress()).getHostString());
|
||||
}
|
||||
|
||||
+14
-15
@@ -41,6 +41,7 @@
|
||||
<properties>
|
||||
<maven.compiler.source>16</maven.compiler.source>
|
||||
<maven.compiler.target>16</maven.compiler.target>
|
||||
<plugin.config.version>3</plugin.config.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
@@ -71,22 +72,24 @@
|
||||
<version>4.1.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- MiniMessage -->
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-api</artifactId>
|
||||
<version>4.14.0</version>
|
||||
<version>4.15.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-text-minimessage</artifactId>
|
||||
<version>4.14.0</version>
|
||||
<version>4.15.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-text-serializer-legacy</artifactId>
|
||||
<version>4.14.0</version>
|
||||
<version>4.15.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -95,12 +98,6 @@
|
||||
<version>2.10.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>4.11.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.unascribed</groupId>
|
||||
<artifactId>flexver-java</artifactId>
|
||||
@@ -110,13 +107,15 @@
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>32.1.3-jre</version>
|
||||
<version>33.0.0-jre</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Plugins -->
|
||||
<dependency>
|
||||
<groupId>net.william278</groupId>
|
||||
<artifactId>papiproxybridge</artifactId>
|
||||
<version>1.4.2</version>
|
||||
<version>1.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -128,9 +127,9 @@
|
||||
|
||||
<!-- Test dependencies -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.2</version>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.10.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -147,7 +146,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<version>3.12.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
||||
@@ -31,6 +31,7 @@ import ch.andre601.advancedserverlist.core.check.UpdateChecker;
|
||||
import ch.andre601.advancedserverlist.core.commands.CommandHandler;
|
||||
import ch.andre601.advancedserverlist.core.file.FileHandler;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionEngine;
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.PlayerHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -47,6 +48,7 @@ public class AdvancedServerList<F>{
|
||||
private final CommandHandler commandHandler;
|
||||
private final PlayerHandler playerHandler;
|
||||
private final AdvancedServerListAPI api = AdvancedServerListAPI.get();
|
||||
private final ExpressionEngine expressionEngine = new ExpressionEngine();
|
||||
|
||||
private UpdateChecker updateChecker;
|
||||
|
||||
@@ -91,6 +93,10 @@ public class AdvancedServerList<F>{
|
||||
return api;
|
||||
}
|
||||
|
||||
public ExpressionEngine getExpressionEngine(){
|
||||
return expressionEngine;
|
||||
}
|
||||
|
||||
public void disable(){
|
||||
getPlugin().getPluginLogger().info("Saving playercache.json file...");
|
||||
getPlayerHandler().save();
|
||||
@@ -136,7 +142,7 @@ public class AdvancedServerList<F>{
|
||||
}
|
||||
|
||||
if(getFileHandler().loadProfiles()){
|
||||
getPlugin().getPluginLogger().info("Successfully loaded " + getFileHandler().getProfiles().size() + " profiles!");
|
||||
getPlugin().getPluginLogger().info("Successfully loaded %d profile(s)!", getFileHandler().getProfiles().size());
|
||||
}else{
|
||||
getPlugin().getPluginLogger().warn("Unable to load profiles! Check previous lines for errors.");
|
||||
return;
|
||||
|
||||
@@ -30,18 +30,17 @@ import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.unascribed.flexver.FlexVerComparator;
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
@@ -49,12 +48,10 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class UpdateChecker{
|
||||
|
||||
private final String url = "https://api.modrinth.com/v2/project/advancedserverlist/version?loaders=[\"%s\"]";
|
||||
private final OkHttpClient client = new OkHttpClient();
|
||||
|
||||
private final AdvancedServerList<?> core;
|
||||
private final PluginLogger logger;
|
||||
private final String loader;
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
// 'https://api.modrinth.com/v2/project/advancedserverlist/version?loaders=["%s"]' URL encoded.
|
||||
private final String url = "https://api.modrinth.com/v2/project/advancedserverlist/version?loaders=%%5B%%22%s%%22%%5D";
|
||||
private final HttpClient client = HttpClient.newHttpClient();
|
||||
|
||||
private final Type listType = new TypeToken<ArrayList<ModrinthVersion>>(){}.getType();
|
||||
private final Gson gson = new GsonBuilder()
|
||||
@@ -65,6 +62,10 @@ public class UpdateChecker{
|
||||
|
||||
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new UpdateCheckThread());
|
||||
|
||||
private final AdvancedServerList<?> core;
|
||||
private final PluginLogger logger;
|
||||
private final String loader;
|
||||
|
||||
public UpdateChecker(AdvancedServerList<?> core){
|
||||
this.core = core;
|
||||
this.logger = core.getPlugin().getPluginLogger();
|
||||
@@ -73,42 +74,13 @@ public class UpdateChecker{
|
||||
startUpdateChecker();
|
||||
}
|
||||
|
||||
public void startUpdateChecker(){
|
||||
executor.scheduleAtFixedRate(() -> {
|
||||
logger.info("Checking for a new update...");
|
||||
checkUpdate().whenComplete((version, throwable) -> {
|
||||
if(version == null || throwable != null){
|
||||
logger.warn("Failed to look for any updates. See previous messages for reasons.");
|
||||
return;
|
||||
}
|
||||
|
||||
int result = version.compare(core.getVersion());
|
||||
switch(result){
|
||||
case -1 -> printUpdateBanner(version.getVersionNumber(), version.getId(), version.isRelease());
|
||||
case 0 -> logger.info("No new update found. You're running the latest version!");
|
||||
case 1 -> logger.info(
|
||||
"Your version (%s) is higher than the latest release (%s). Are you running a dev build?",
|
||||
core.getVersion(), version.getVersionNumber()
|
||||
);
|
||||
}
|
||||
});
|
||||
}, 0L, 12L, TimeUnit.HOURS);
|
||||
}
|
||||
|
||||
public void disable(){
|
||||
executor.shutdown();
|
||||
client.dispatcher().executorService().shutdown();
|
||||
try{
|
||||
if(!executor.awaitTermination(1, TimeUnit.SECONDS)){
|
||||
executor.shutdownNow();
|
||||
if(!executor.awaitTermination(1, TimeUnit.SECONDS))
|
||||
logger.warn("Scheduler didn't terminate in time!");
|
||||
}
|
||||
|
||||
if(!client.dispatcher().executorService().awaitTermination(1, TimeUnit.SECONDS)){
|
||||
client.dispatcher().executorService().shutdownNow();
|
||||
if(!client.dispatcher().executorService().awaitTermination(1, TimeUnit.SECONDS))
|
||||
logger.warn("OkHttp's Scheduler didn't terminate in time!");
|
||||
logger.warn("Scheduler did not terminate in time!");
|
||||
}
|
||||
}catch(InterruptedException ex){
|
||||
executor.shutdownNow();
|
||||
@@ -116,108 +88,93 @@ public class UpdateChecker{
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<ModrinthVersion> checkUpdate(){
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
PluginLogger logger = core.getPlugin().getPluginLogger();
|
||||
if(core.getVersion().equals("UNKNOWN")){
|
||||
logger.warn("Cannot perform Update check! Plugin version couldn't be parsed.");
|
||||
return null;
|
||||
}
|
||||
private void startUpdateChecker(){
|
||||
executor.scheduleAtFixedRate(() -> {
|
||||
logger.info("Looking for an update...");
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(String.format(url, loader))
|
||||
.header("User-Agent", "AdvancedServerList-" + loader + "/" + core.getVersion())
|
||||
.build();
|
||||
|
||||
try(Response response = client.newCall(request).execute()){
|
||||
if(!response.isSuccessful()){
|
||||
logger.warn("Encountered a non-successful response from Modrinth! Code: %d", response.code());
|
||||
return null;
|
||||
}
|
||||
|
||||
ResponseBody body = response.body();
|
||||
if(body == null){
|
||||
logger.warn("Received an empty Response body from Modrinth!");
|
||||
return null;
|
||||
performUpdateCheck().whenComplete((version, throwable) -> {
|
||||
if(version == null || throwable != null){
|
||||
logger.warn("Failed to look for any updates. Check previous messages for causes.");
|
||||
return;
|
||||
}
|
||||
|
||||
String responseString = body.string();
|
||||
if(responseString.isEmpty()){
|
||||
logger.warn("Received an empty Response body from Modrinth!");
|
||||
return null;
|
||||
logger.debug(UpdateChecker.class, "Comparing versions...");
|
||||
|
||||
int result = version.compare(core.getVersion());
|
||||
switch(result){
|
||||
case -1 -> printUpdateBanner(version);
|
||||
case 0 -> logger.info("You are running the latest version!");
|
||||
case 1 -> logger.info(
|
||||
"Your version (%s) seems to be newer than the latest release (%s). Are you running a dev build?",
|
||||
core.getVersion(), version.versionNumber()
|
||||
);
|
||||
}
|
||||
|
||||
List<ModrinthVersion> list = gson.fromJson(responseString, listType);
|
||||
if(list == null || list.isEmpty()){
|
||||
logger.warn("Couldn't convert JSON Array into a valid list.");
|
||||
return null;
|
||||
}
|
||||
|
||||
ModrinthVersion version = list.get(0);
|
||||
|
||||
if(version.getVersionNumber() == null || version.getVersionNumber().isEmpty()){
|
||||
logger.warn("Cannot check latest version. Received version number was null/empty.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return version;
|
||||
}catch(JsonSyntaxException ex){
|
||||
logger.warn("Encountered invalid JSON from Response body!", ex);
|
||||
return null;
|
||||
}catch(IOException ex){
|
||||
logger.warn("Encountered Exception while checking for an update!", ex);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
});
|
||||
}, 0L, 12L, TimeUnit.HOURS);
|
||||
}
|
||||
|
||||
private void printUpdateBanner(String version, String versionId, boolean isRelease){
|
||||
private CompletableFuture<ModrinthVersion> performUpdateCheck(){
|
||||
String finalUrl = String.format(url, loader);
|
||||
|
||||
logger.debug(UpdateChecker.class, "Checking '%s' for updates...", finalUrl);
|
||||
|
||||
if(core.getVersion().equals("UNKNOWN")){
|
||||
logger.warn("Cannot perform update check. Plugin version is 'UNKNOWN'!");
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
HttpRequest request;
|
||||
try{
|
||||
request = HttpRequest.newBuilder()
|
||||
.uri(new URI(finalUrl))
|
||||
.header("User-Agent", "AdvancedServerList-" + loader + "/" + core.getVersion())
|
||||
.build();
|
||||
}catch(URISyntaxException ex){
|
||||
logger.warn("Cannot perform update check. URL '%s' is not a valid URI.", ex, finalUrl);
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8))
|
||||
.thenApply(response -> new ArrayList<ModrinthVersion>(gson.fromJson(response.body(), listType)))
|
||||
.thenApply(list -> list.get(0))
|
||||
.exceptionally((throwable) -> {
|
||||
logger.warn("Encountered exception while performing update check!", throwable);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void printUpdateBanner(ModrinthVersion version){
|
||||
logger.info("==================================================================");
|
||||
logger.info("You are running an outdated version of AdvancedServerList!");
|
||||
logger.info("");
|
||||
logger.info("Your version: %s", core.getVersion());
|
||||
logger.info("Modrinth version: %s", version);
|
||||
logger.info("Modrinth: %s", version.versionNumber());
|
||||
logger.info("");
|
||||
|
||||
if(!isRelease){
|
||||
logger.info("WARNING: This release is an Alpha/Beta! It may contain");
|
||||
logger.info(" breaking changes!");
|
||||
if(!version.isRelease()){
|
||||
logger.info("WARNING!");
|
||||
logger.info("This is a %s version and may contain breaking changes and/or bugs!", version.versionType());
|
||||
logger.info("");
|
||||
}
|
||||
|
||||
logger.info("You can download the latest release from here:");
|
||||
logger.info("https://modrinth.com/plugin/advancedserverlist/version/%s", versionId);
|
||||
logger.info("Download the latest version from here:");
|
||||
logger.info("https://modrinth.com/plugin/advancedserverlist/version/%s", version.id());
|
||||
logger.info("==================================================================");
|
||||
}
|
||||
|
||||
public static class ModrinthVersion{
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
private String id;
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
private String versionNumber;
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
private String versionType;
|
||||
|
||||
public ModrinthVersion(String id, String versionNumber, String versionType){
|
||||
this.id = id;
|
||||
this.versionNumber = versionNumber;
|
||||
this.versionType = versionType;
|
||||
}
|
||||
|
||||
public String getId(){
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getVersionNumber(){
|
||||
return versionNumber;
|
||||
}
|
||||
public record ModrinthVersion(String id, String versionNumber, String versionType){
|
||||
|
||||
public boolean isRelease(){
|
||||
return versionType.equals("release");
|
||||
return versionType().equals("release");
|
||||
}
|
||||
|
||||
public int compare(String version){
|
||||
return FlexVerComparator.compare(version, versionNumber);
|
||||
return FlexVerComparator.compare(version, versionNumber());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return String.format("ModrinthVersion{id=%s,versionNumber=%s,versionType=%s}", id, versionNumber, versionType);
|
||||
}
|
||||
}
|
||||
}
|
||||
+43
-4
@@ -30,6 +30,7 @@ import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.compat.maintenance.MaintenanceUtil;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
|
||||
import ch.andre601.advancedserverlist.core.compat.papi.PAPIUtil;
|
||||
@@ -44,11 +45,17 @@ public class PingEventHandler{
|
||||
private static MaintenanceUtil maintenanceUtil = null;
|
||||
|
||||
public static <F, P extends GenericPlayer> void handleEvent(GenericEventWrapper<F, P> event){
|
||||
if(event.isInvalidProtocol() || event.isMaintenanceModeActive())
|
||||
event.getPlugin().getPluginLogger().debug(PingEventHandler.class, "Received ping event. Handling it...");
|
||||
if(event.isInvalidProtocol() || event.isMaintenanceModeActive()){
|
||||
event.getPlugin().getPluginLogger().debug(PingEventHandler.class, "Not handling event. Either protocol was invalid of Maintenance is enabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
PluginCore<F> plugin = event.getPlugin();
|
||||
String host = event.getVirtualHost();
|
||||
PluginLogger logger = plugin.getPluginLogger();
|
||||
|
||||
logger.debug(PingEventHandler.class, "Protocol valid. Continue handling...");
|
||||
|
||||
int online = event.getOnlinePlayers();
|
||||
int max = event.getMaxPlayers();
|
||||
@@ -61,32 +68,50 @@ public class PingEventHandler{
|
||||
|
||||
ServerListProfile profile = ProfileManager.resolveProfile(plugin.getCore(), player, server);
|
||||
|
||||
if(profile == null)
|
||||
if(profile == null){
|
||||
logger.debugWarn(PingEventHandler.class, "Server List Profile couldn't be resolved properly. Cancelling event handling...");
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug(PingEventHandler.class, "Received valid Server List Profile. Calling PreServerListSetEvent...");
|
||||
|
||||
GenericServerListEvent e = event.callEvent(ProfileManager.merge(profile));
|
||||
if(e == null || e.isCancelled())
|
||||
if(e == null || e.isCancelled()){
|
||||
logger.debug(PingEventHandler.class, "PreServerListSetEvent was cancelled. Stopping ping handling...");
|
||||
return;
|
||||
}
|
||||
|
||||
logger.debug(PingEventHandler.class, "PreServerListSetEvent completed. Proceeding with ping handling...");
|
||||
|
||||
ProfileEntry entry = e.getEntry();
|
||||
if(entry.isInvalid())
|
||||
if(entry.isInvalid()){
|
||||
logger.debugWarn(PingEventHandler.class, "No valid ProfileEntry retrieved. Cancelling ping handling...");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean extraPlayers = ProfileManager.checkOption(entry.extraPlayersEnabled());
|
||||
|
||||
if(extraPlayers){
|
||||
max = online + (entry.extraPlayersCount() == null ? 0 : entry.extraPlayersCount());
|
||||
|
||||
logger.debug(PingEventHandler.class, "Extra Players enabled. Applying '%d' as max player count...", max);
|
||||
|
||||
event.setMaxPlayers(max);
|
||||
}
|
||||
|
||||
if(ProfileManager.checkOption(entry.maxPlayersEnabled()) && !extraPlayers){
|
||||
max = (entry.maxPlayersCount() == null) ? 0 : entry.maxPlayersCount();
|
||||
|
||||
logger.debug(PingEventHandler.class, "Max Players enabled. Applying '%d' as max player count...", max);
|
||||
|
||||
event.setMaxPlayers(max);
|
||||
}
|
||||
|
||||
GenericServer finalServer = event.createGenericServer(online, max, host);
|
||||
|
||||
if(ProfileManager.checkOption(entry.motd())){
|
||||
logger.debug(PingEventHandler.class, "MOTD set. Applying '%s'...", String.join("\\n", entry.motd()));
|
||||
|
||||
event.setMotd(
|
||||
ComponentParser.list(entry.motd())
|
||||
.modifyText(text -> StringReplacer.replace(text, player, finalServer))
|
||||
@@ -98,10 +123,14 @@ public class PingEventHandler{
|
||||
boolean hidePlayers = ProfileManager.checkOption(entry.hidePlayersEnabled());
|
||||
|
||||
if(hidePlayers){
|
||||
logger.debug(PingEventHandler.class, "Hide Players enabled. Hiding player count...");
|
||||
|
||||
event.hidePlayers();
|
||||
}
|
||||
|
||||
if(ProfileManager.checkOption(entry.playerCountText()) && !hidePlayers){
|
||||
logger.debug(PingEventHandler.class, "Player Count Text set. Applying '%s'...", entry.playerCountText());
|
||||
|
||||
event.setPlayerCount(
|
||||
ComponentParser.text(entry.playerCountText())
|
||||
.modifyText(text -> StringReplacer.replace(text, player, finalServer))
|
||||
@@ -111,14 +140,19 @@ public class PingEventHandler{
|
||||
}
|
||||
|
||||
if(ProfileManager.checkOption(entry.players()) && !hidePlayers){
|
||||
logger.debug(PingEventHandler.class, "Player Count Hover set. Applying '%s'...", String.join("\\n", entry.players()));
|
||||
|
||||
event.setPlayers(entry.players(), player, server);
|
||||
}
|
||||
|
||||
if(ProfileManager.checkOption(entry.favicon())){
|
||||
logger.debug(PingEventHandler.class, "Favicon set. Resolving '%s'...", entry.favicon());
|
||||
|
||||
String favicon = StringReplacer.replace(entry.favicon(), player, server);
|
||||
|
||||
F fav = plugin.getFaviconHandler().getFavicon(favicon, image -> {
|
||||
try{
|
||||
logger.debug(PingEventHandler.class, "Converting BufferedImage to Server or Proxy Favicon instance...");
|
||||
return event.createFavicon(image);
|
||||
}catch(Exception ex){
|
||||
plugin.getPluginLogger().warn("Encountered an Exception while creating Favicon!", ex);
|
||||
@@ -127,12 +161,17 @@ public class PingEventHandler{
|
||||
});
|
||||
|
||||
if(fav == null){
|
||||
logger.debugWarn(PingEventHandler.class, "Favicon was invalid or not yet resolved! Using default favicon of Server/Proxy...");
|
||||
|
||||
event.setDefaultFavicon();
|
||||
}else{
|
||||
logger.debug(PingEventHandler.class, "Applying favicon...");
|
||||
|
||||
event.setFavicon(fav);
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug(PingEventHandler.class, "Event handling completed. Updating Ping data...");
|
||||
event.updateEvent();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.file;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import org.spongepowered.configurate.ConfigurateException;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
@@ -32,16 +33,31 @@ import org.spongepowered.configurate.NodePath;
|
||||
import org.spongepowered.configurate.transformation.ConfigurationTransformation;
|
||||
import org.spongepowered.configurate.transformation.TransformAction;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
public class ConfigMigrator{
|
||||
|
||||
public static final int LATEST = 1;
|
||||
public static final int LATEST = resolveConfigVersion();
|
||||
|
||||
private ConfigMigrator(){}
|
||||
|
||||
public static ConfigurationTransformation.Versioned create(){
|
||||
return ConfigurationTransformation.versionedBuilder()
|
||||
.versionKey("configVersion")
|
||||
.addVersion(LATEST, oneToTwo())
|
||||
.addVersion(LATEST, twoToThree())
|
||||
.addVersion(2, oneToTwo())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ConfigurationTransformation twoToThree(){
|
||||
return ConfigurationTransformation.builder()
|
||||
.addAction(NodePath.path(), ((path, value) -> {
|
||||
value.node("debug").set(false);
|
||||
|
||||
return null;
|
||||
}))
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -67,9 +83,21 @@ public class ConfigMigrator{
|
||||
versioned.apply(node);
|
||||
final int endVersion = versioned.version(node);
|
||||
if(startVersion < endVersion)
|
||||
logger.info("Migrated config.yml from " + startVersion + " to " + endVersion);
|
||||
logger.info("Migrated config.yml from v" + startVersion + " to v" + endVersion);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private static int resolveConfigVersion(){
|
||||
try(InputStream is = AdvancedServerList.class.getResourceAsStream("/version.properties")){
|
||||
Properties properties = new Properties();
|
||||
|
||||
properties.load(is);
|
||||
|
||||
return Integer.parseInt(properties.getProperty("config-version"));
|
||||
}catch(IOException | NumberFormatException ex){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,7 +157,7 @@ public class FileHandler{
|
||||
continue;
|
||||
|
||||
profiles.add(ServerListProfile.Builder.resolve(file.getName(), tmp, logger).build());
|
||||
logger.info("Loaded " + file.getName());
|
||||
logger.info("Loaded '%s'!", file.getName());
|
||||
}
|
||||
|
||||
if(profiles.isEmpty()){
|
||||
@@ -178,7 +178,7 @@ public class FileHandler{
|
||||
try{
|
||||
return loader.load();
|
||||
}catch(IOException ex){
|
||||
logger.warn("Cannot load " + path.toFile().getName() + " due to an IOException!", ex);
|
||||
logger.warn("Cannot load '%s' due to an IOException!", ex, path.toFile().getName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -214,7 +214,7 @@ public class FileHandler{
|
||||
}
|
||||
|
||||
Files.copy(config, configBackup.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
logger.info("Saved backup as '" + configBackup.getName() + "'!");
|
||||
logger.info("Saved backup as '%s'!", configBackup.getName());
|
||||
|
||||
return true;
|
||||
}catch(IOException ex){
|
||||
|
||||
@@ -27,6 +27,10 @@ package ch.andre601.advancedserverlist.core.interfaces;
|
||||
|
||||
public interface PluginLogger{
|
||||
|
||||
void debug(Class<?> clazz, String msg, Object... args);
|
||||
|
||||
void debugWarn(Class<?> clazz, String msg, Object... args);
|
||||
|
||||
void info(String msg, Object... args);
|
||||
|
||||
void warn(String msg, Object... args);
|
||||
|
||||
@@ -54,4 +54,8 @@ public interface PluginCore<F>{
|
||||
String getPlatformVersion();
|
||||
|
||||
String getLoader();
|
||||
|
||||
default boolean isDebugEnabled(){
|
||||
return getCore().getFileHandler().getBoolean("debug");
|
||||
}
|
||||
}
|
||||
+42
-3
@@ -30,16 +30,22 @@ import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.Expression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionEngine;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionErrorTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class ServerListProfile{
|
||||
|
||||
private final int priority;
|
||||
private final String condition;
|
||||
private final List<Expression> expressions;
|
||||
private final ProfileEntry defaultProfile;
|
||||
|
||||
@@ -47,8 +53,9 @@ public class ServerListProfile{
|
||||
|
||||
private final Random random = new Random();
|
||||
|
||||
public ServerListProfile(int priority, List<Expression> expressions, ProfileEntry defaultProfile, List<ProfileEntry> profiles){
|
||||
public ServerListProfile(int priority, String condition, List<Expression> expressions, ProfileEntry defaultProfile, List<ProfileEntry> profiles){
|
||||
this.priority = priority;
|
||||
this.condition = condition;
|
||||
this.expressions = expressions;
|
||||
this.defaultProfile = defaultProfile;
|
||||
|
||||
@@ -59,7 +66,17 @@ public class ServerListProfile{
|
||||
return priority;
|
||||
}
|
||||
|
||||
public boolean evalConditions(GenericPlayer player, GenericServer server){
|
||||
public boolean evalConditions(ExpressionEngine expressionEngine, PluginLogger logger, GenericPlayer player, GenericServer server){
|
||||
if(condition != null && !condition.isEmpty()){
|
||||
ExpressionTemplate template = expressionEngine.compile(condition, logger, player, server);
|
||||
if(template instanceof ExpressionErrorTemplate errorTemplate){
|
||||
logger.warn(errorTemplate.instantiateWithStringResult().evaluate());
|
||||
return true;
|
||||
}
|
||||
|
||||
return template.instantiateWithBooleanResult().evaluate();
|
||||
}
|
||||
|
||||
if(expressions.isEmpty())
|
||||
return true;
|
||||
|
||||
@@ -121,6 +138,7 @@ public class ServerListProfile{
|
||||
|
||||
private final PluginLogger logger;
|
||||
|
||||
private String condition = null;
|
||||
private List<ProfileEntry> profiles = new ArrayList<>();
|
||||
private ProfileEntry defaultProfile = ProfileEntry.empty();
|
||||
|
||||
@@ -133,11 +151,21 @@ public class ServerListProfile{
|
||||
|
||||
public static Builder resolve(String fileName, ConfigurationNode node, PluginLogger logger){
|
||||
return new Builder(fileName, node, logger)
|
||||
.resolveCondition()
|
||||
.resolveExpressions()
|
||||
.resolveProfiles()
|
||||
.resolveDefaultProfile();
|
||||
}
|
||||
|
||||
private Builder resolveCondition(){
|
||||
String condition = node.node("condition").getString();
|
||||
if(condition == null || condition.isEmpty())
|
||||
return this;
|
||||
|
||||
this.condition = condition;
|
||||
return this;
|
||||
}
|
||||
|
||||
private Builder resolveExpressions(){
|
||||
List<String> temp;
|
||||
try{
|
||||
@@ -150,6 +178,8 @@ public class ServerListProfile{
|
||||
if(temp == null || temp.isEmpty())
|
||||
return this;
|
||||
|
||||
StringJoiner joiner = new StringJoiner(" and ");
|
||||
|
||||
for(String str : temp){
|
||||
Expression expr = Expression.resolve(str);
|
||||
|
||||
@@ -158,9 +188,18 @@ public class ServerListProfile{
|
||||
continue;
|
||||
}
|
||||
|
||||
joiner.add(str);
|
||||
this.expressions.add(expr);
|
||||
}
|
||||
|
||||
if(!this.expressions.isEmpty()){
|
||||
logger.warn("'%s' uses 'conditions' which is deprecated in favour of the newer 'condition' option.", fileName);
|
||||
logger.warn("The 'conditions' option will be removed in a future version.");
|
||||
logger.warn("");
|
||||
logger.warn("Please migrate your condition(s) over from the old option to the new option like this:");
|
||||
logger.warn("consition: '%s'", joiner.toString());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -184,7 +223,7 @@ public class ServerListProfile{
|
||||
}
|
||||
|
||||
public ServerListProfile build(){
|
||||
return new ServerListProfile(this.priority, this.expressions, this.defaultProfile, this.profiles);
|
||||
return new ServerListProfile(this.priority, this.condition, this.expressions, this.defaultProfile, this.profiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.AbstractUnaryToBooleanExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.AbstractUnaryToDoubleExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.AbstractUnaryToStringExpression;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
|
||||
public class Conversions{
|
||||
|
||||
private final static NumberFormat NUMBER_FORMAT;
|
||||
|
||||
static {
|
||||
NUMBER_FORMAT = NumberFormat.getNumberInstance(Locale.ROOT);
|
||||
NUMBER_FORMAT.setGroupingUsed(false);
|
||||
}
|
||||
|
||||
public static ToBooleanExpression toBoolean(ToDoubleExpression expression){
|
||||
return new AbstractUnaryToBooleanExpression<>(expression) {
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return delegate.evaluate() != 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression toBoolean(ToStringExpression expression){
|
||||
return new AbstractUnaryToBooleanExpression<>(expression) {
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return Boolean.parseBoolean(delegate.evaluate());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToDoubleExpression toDouble(ToBooleanExpression expression){
|
||||
return new AbstractUnaryToDoubleExpression<>(expression) {
|
||||
@Override
|
||||
public double evaluate(){
|
||||
return delegate.evaluate() ? 1 : 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToDoubleExpression toDouble(ToStringExpression expression){
|
||||
return new AbstractUnaryToDoubleExpression<>(expression) {
|
||||
@Override
|
||||
public double evaluate(){
|
||||
String result = delegate.evaluate();
|
||||
try{
|
||||
return NUMBER_FORMAT.parse(result).doubleValue();
|
||||
}catch(ParseException | NumberFormatException ex){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToStringExpression toString(ToBooleanExpression expression){
|
||||
return new AbstractUnaryToStringExpression<>(expression) {
|
||||
@Override
|
||||
public String evaluate(){
|
||||
return Boolean.toString(delegate.evaluate());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToStringExpression toString(ToDoubleExpression expression){
|
||||
return new AbstractUnaryToStringExpression<>(expression) {
|
||||
@Override
|
||||
public String evaluate(){
|
||||
double result = delegate.evaluate();
|
||||
return result == (int)result ? Integer.toString((int)result) : Double.toString(result);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers.TokenReader;
|
||||
import com.google.common.collect.Ordering;
|
||||
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class ExpressionTokenizer{
|
||||
|
||||
private static final Ordering<TokenReader> TOKEN_READER_ORDERING = Ordering.from(Comparator.comparingInt(TokenReader::getPriority)).reverse();
|
||||
|
||||
private final List<TokenReader> tokenReaders;
|
||||
|
||||
public ExpressionTokenizer(Iterable<TokenReader> tokenReaders){
|
||||
this.tokenReaders = TOKEN_READER_ORDERING.immutableSortedCopy(tokenReaders);
|
||||
}
|
||||
|
||||
public List<Token> parse(String text, PluginLogger logger, GenericPlayer player, GenericServer server){
|
||||
ParsePosition position = new ParsePosition(0);
|
||||
|
||||
List<Token> tokens = new LinkedList<>();
|
||||
|
||||
next_token:
|
||||
while(true){
|
||||
while(position.getIndex() < text.length() && Character.isWhitespace(text.charAt(position.getIndex()))){
|
||||
position.setIndex(position.getIndex() + 1);
|
||||
}
|
||||
|
||||
if(position.getIndex() >= text.length())
|
||||
break;
|
||||
|
||||
for(TokenReader tokenReader : tokenReaders){
|
||||
Token token;
|
||||
if(null != (token = tokenReader.read(text, position, player, server))){
|
||||
tokens.add(token);
|
||||
continue next_token;
|
||||
}
|
||||
}
|
||||
|
||||
logger.warn("Illegal token '%c' at index %d.", text.charAt(position.getIndex()), position.getIndex());
|
||||
break;
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
|
||||
|
||||
public interface Expression{}
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.ExpressionTokenizer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.ListOperator;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.Operator;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.parsers.*;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.BooleanToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.DefaultTokens;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers.*;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ExpressionEngine{
|
||||
|
||||
private final ExpressionTokenizer tokenizer;
|
||||
private final ExpressionTemplateParser templateParser;
|
||||
|
||||
public ExpressionEngine(){
|
||||
Options options = new Options.Builder()
|
||||
.withDefaultTokenReaders()
|
||||
.withDefaultOperators()
|
||||
.withDefaultValueReaders()
|
||||
.build();
|
||||
|
||||
this.tokenizer = new ExpressionTokenizer(options.tokenReaders);
|
||||
this.templateParser = new ExpressionTemplateParser(options.operators, options.valueReaders);
|
||||
}
|
||||
|
||||
public ExpressionTemplate compile(String expression, PluginLogger logger, GenericPlayer player, GenericServer server){
|
||||
return templateParser.parse(tokenizer.parse(expression, logger, player, server));
|
||||
}
|
||||
|
||||
public static class Options{
|
||||
|
||||
private final List<TokenReader> tokenReaders;
|
||||
private final ImmutableMap<Token, Operator> operators;
|
||||
private final ImmutableList<ValueReader> valueReaders;
|
||||
|
||||
private Options(List<TokenReader> tokenReaders, ImmutableMap<Token, Operator> operators, ImmutableList<ValueReader> valueReaders){
|
||||
this.tokenReaders = tokenReaders;
|
||||
this.operators = operators;
|
||||
this.valueReaders = valueReaders;
|
||||
}
|
||||
|
||||
public static class Builder{
|
||||
private final List<TokenReader> tokenReaders = new ArrayList<>();
|
||||
private final Map<Token, Operator> operators = new HashMap<>();
|
||||
private final List<ValueReader> valueReaders = new ArrayList<>();
|
||||
|
||||
public Builder(){}
|
||||
|
||||
public Builder withDefaultTokenReaders(){
|
||||
return this
|
||||
.tokenReader(new PatternTokenReader(BooleanToken.FALSE, "false"))
|
||||
.tokenReader(new PatternTokenReader(BooleanToken.TRUE, "true"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.AND, "and"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.AND, "&&"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.OR, "or"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.OR, "||"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL, "=="))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL, "="))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.NOT_EQUAL, "!="))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL_IGNORE_CASE, "~="))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.NOT_EQUAL_IGNORE_CASE, "!~"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.STARTS_WITH, "|-"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.ENDS_WITH, "-|"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.CONTAINS, "<-"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.GREATER_OR_EQUAL_THAN, ">="))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.LESSER_OR_EQUAL_THAN, "<="))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.OPENING_PARENTHESIS, "("))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.CLOSING_PARENTHESIS, ")"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.NEGATION, "!"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.GREATER_THAN, ">"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.LESSER_THAN, "<"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.CONCAT_STRING, "."))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.ADD, "+"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.SUB, "-"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.MULT, "*"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.DIV, "/"))
|
||||
.tokenReader(new QuotedLiteralTokenReader(-10, '\"'))
|
||||
.tokenReader(new QuotedLiteralTokenReader(-10, '\''))
|
||||
.tokenReader(new PlaceholderTokenReader(-20))
|
||||
.tokenReader(new NumberTokenReader(-50))
|
||||
.tokenReader(new NonQuotedLiteralTokenReader(-100));
|
||||
}
|
||||
|
||||
public Builder withDefaultOperators(){
|
||||
return this
|
||||
.operator(DefaultTokens.AND, ListOperator.of(100, ExpressionTemplates::and))
|
||||
.operator(DefaultTokens.OR, ListOperator.of(50, ExpressionTemplates::or))
|
||||
.operator(DefaultTokens.EQUAL, Operator.of(25, ExpressionTemplates::equal))
|
||||
.operator(DefaultTokens.NOT_EQUAL, Operator.of(25, ExpressionTemplates::notEqual))
|
||||
.operator(DefaultTokens.EQUAL_IGNORE_CASE, Operator.of(25, ExpressionTemplates::equalIgnoreCase))
|
||||
.operator(DefaultTokens.NOT_EQUAL_IGNORE_CASE, Operator.of(25, ExpressionTemplates::notEqualIgnoreCase))
|
||||
.operator(DefaultTokens.STARTS_WITH, Operator.of(25, ExpressionTemplates::startsWith))
|
||||
.operator(DefaultTokens.ENDS_WITH, Operator.of(25, ExpressionTemplates::endsWith))
|
||||
.operator(DefaultTokens.CONTAINS, Operator.of(25, ExpressionTemplates::contains))
|
||||
.operator(DefaultTokens.GREATER_THAN, Operator.of(25, ExpressionTemplates::greater))
|
||||
.operator(DefaultTokens.GREATER_OR_EQUAL_THAN, Operator.of(25, ExpressionTemplates::greaterOrEqual))
|
||||
.operator(DefaultTokens.LESSER_THAN, Operator.of(25, ExpressionTemplates::less))
|
||||
.operator(DefaultTokens.LESSER_OR_EQUAL_THAN, Operator.of(25, ExpressionTemplates::lessOrEqual))
|
||||
.operator(DefaultTokens.CONCAT_STRING, ListOperator.of(10, ExpressionTemplates::concat))
|
||||
.operator(DefaultTokens.ADD, ListOperator.of(4, ExpressionTemplates::sum))
|
||||
.operator(DefaultTokens.SUB, Operator.of(3, ExpressionTemplates::sub))
|
||||
.operator(DefaultTokens.MULT, ListOperator.of(2, ExpressionTemplates::product))
|
||||
.operator(DefaultTokens.DIV, Operator.of(1, ExpressionTemplates::div));
|
||||
}
|
||||
|
||||
public Builder withDefaultValueReaders(){
|
||||
return this
|
||||
.valueReader(new BooleanConstantReader())
|
||||
.valueReader(new NumberConstantReader())
|
||||
.valueReader(new StringConstantReader())
|
||||
.valueReader(new NegatedExpressionReader(DefaultTokens.NEGATION))
|
||||
.valueReader(new ParenthesisedExpressionReader(DefaultTokens.OPENING_PARENTHESIS, DefaultTokens.CLOSING_PARENTHESIS))
|
||||
.valueReader(new PlaceholderReader())
|
||||
.valueReader(new NegatedNumberReader(DefaultTokens.SUB));
|
||||
}
|
||||
|
||||
public Builder tokenReader(TokenReader tokenReader){
|
||||
this.tokenReaders.add(tokenReader);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder operator(Token token, Operator operator){
|
||||
this.operators.put(token, operator);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder valueReader(ValueReader valueReader){
|
||||
this.valueReaders.add(valueReader);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Options build(){
|
||||
return new Options(this.tokenReaders, ImmutableMap.copyOf(operators), ImmutableList.copyOf(valueReaders));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.*;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class Expressions{
|
||||
|
||||
public static ToBooleanExpression negate(ToBooleanExpression expression){
|
||||
return new AbstractUnaryToBooleanExpression<>(expression){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return !delegate.evaluate();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression and(Collection<ToBooleanExpression> operands){
|
||||
return new AbstractToBooleanExpression<>(operands){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
for(ToBooleanExpression operand : operands){
|
||||
if(!operand.evaluate())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression or(Collection<ToBooleanExpression> operands){
|
||||
return new AbstractToBooleanExpression<>(operands){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
for(ToBooleanExpression operand : operands){
|
||||
if(operand.evaluate())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToStringExpression concat(Collection<ToStringExpression> operands){
|
||||
return new AbstractToStringExpression<>(operands){
|
||||
@Override
|
||||
public String evaluate(){
|
||||
StringBuilder result = new StringBuilder();
|
||||
for(ToStringExpression operand : operands){
|
||||
result.append(operand.evaluate());
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression equal(ToStringExpression a, ToStringExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return a.evaluate().equals(b.evaluate());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression notEqual(ToStringExpression a, ToStringExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return !a.evaluate().equals(b.evaluate());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression equalIgnoreCase(ToStringExpression a, ToStringExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return a.evaluate().equalsIgnoreCase(b.evaluate());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression notEqualIgnoreCase(ToStringExpression a, ToStringExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return !a.evaluate().equalsIgnoreCase(b.evaluate());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression startsWith(ToStringExpression a, ToStringExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return a.evaluate().startsWith(b.evaluate());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression endsWith(ToStringExpression a, ToStringExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return a.evaluate().endsWith(b.evaluate());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression contains(ToStringExpression a, ToStringExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return a.evaluate().contains(b.evaluate());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression greaterThan(ToDoubleExpression a, ToDoubleExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return a.evaluate() > b.evaluate();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression greaterOrEqualThan(ToDoubleExpression a, ToDoubleExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return a.evaluate() >= b.evaluate();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression lessThan(ToDoubleExpression a, ToDoubleExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return a.evaluate() < b.evaluate();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToBooleanExpression lessOrEqualThan(ToDoubleExpression a, ToDoubleExpression b){
|
||||
return new AbstractBinaryToBooleanExpression<>(a, b){
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return a.evaluate() <= b.evaluate();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToDoubleExpression sum(Collection<ToDoubleExpression> operands){
|
||||
return new AbstractToDoubleExpression<>(operands){
|
||||
@Override
|
||||
public double evaluate(){
|
||||
double result = 0;
|
||||
for(ToDoubleExpression operand : operands){
|
||||
result += operand.evaluate();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToDoubleExpression product(Collection<ToDoubleExpression> operands){
|
||||
return new AbstractToDoubleExpression<>(operands){
|
||||
@Override
|
||||
public double evaluate(){
|
||||
double result = 1;
|
||||
for(ToDoubleExpression operand : operands){
|
||||
result *= operand.evaluate();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToDoubleExpression sub(ToDoubleExpression a, ToDoubleExpression b){
|
||||
return new AbstractBinaryToDoubleExpression<>(a, b){
|
||||
@Override
|
||||
public double evaluate(){
|
||||
return a.evaluate() - b.evaluate();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToDoubleExpression div(ToDoubleExpression a, ToDoubleExpression b){
|
||||
return new AbstractBinaryToDoubleExpression<>(a, b){
|
||||
@Override
|
||||
public double evaluate(){
|
||||
return a.evaluate() / b.evaluate();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static ToDoubleExpression negateNumber(ToDoubleExpression a){
|
||||
return new AbstractUnaryToDoubleExpression<>(a){
|
||||
@Override
|
||||
public double evaluate(){
|
||||
return -delegate.evaluate();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
|
||||
|
||||
public interface ToBooleanExpression extends Expression{
|
||||
|
||||
boolean evaluate();
|
||||
|
||||
static ToBooleanExpression literal(boolean value){
|
||||
return new ConstantToBooleanExpression(value);
|
||||
}
|
||||
|
||||
class ConstantToBooleanExpression implements ToBooleanExpression{
|
||||
|
||||
private final boolean value;
|
||||
|
||||
public ConstantToBooleanExpression(boolean value){
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean evaluate(){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
|
||||
|
||||
public interface ToDoubleExpression extends Expression{
|
||||
|
||||
double evaluate();
|
||||
|
||||
static ToDoubleExpression literal(double value){
|
||||
return new ConstantToDoubleExpression(value);
|
||||
}
|
||||
|
||||
class ConstantToDoubleExpression implements ToDoubleExpression{
|
||||
|
||||
private final double value;
|
||||
|
||||
public ConstantToDoubleExpression(double value){
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double evaluate(){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
|
||||
|
||||
public interface ToStringExpression extends Expression{
|
||||
|
||||
String evaluate();
|
||||
|
||||
static ToStringExpression literal(String value){
|
||||
return new ConstantToStringExpression(value);
|
||||
}
|
||||
|
||||
class ConstantToStringExpression implements ToStringExpression{
|
||||
|
||||
private final String value;
|
||||
|
||||
private ConstantToStringExpression(String value){
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String evaluate(){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.operators;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class ListOperator extends Operator{
|
||||
|
||||
public ListOperator(int priority){
|
||||
super(priority);
|
||||
}
|
||||
|
||||
public static ListOperator of(int priority, Function<Collection<ExpressionTemplate>, ExpressionTemplate> function){
|
||||
return new ListOperator(priority){
|
||||
@Override
|
||||
public ExpressionTemplate createTemplate(List<ExpressionTemplate> operands){
|
||||
return function.apply(operands);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionTemplate createTemplate(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return createTemplate(Arrays.asList(a, b));
|
||||
}
|
||||
|
||||
public abstract ExpressionTemplate createTemplate(List<ExpressionTemplate> operands);
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.operators;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public abstract class Operator{
|
||||
|
||||
private final int priority;
|
||||
|
||||
public Operator(int priority){
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public static Operator of(int priority, BiFunction<ExpressionTemplate, ExpressionTemplate, ExpressionTemplate> function){
|
||||
return new Operator(priority){
|
||||
@Override
|
||||
public ExpressionTemplate createTemplate(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return function.apply(a, b);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int getPriority(){
|
||||
return priority;
|
||||
}
|
||||
|
||||
public abstract ExpressionTemplate createTemplate(ExpressionTemplate a, ExpressionTemplate b);
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ConstantExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.BooleanToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BooleanConstantReader extends ValueReader{
|
||||
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
if(tokenList.get(0) instanceof BooleanToken){
|
||||
return ConstantExpressionTemplate.of(((BooleanToken)tokenList.remove(0)).getValue());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.ListOperator;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.Operator;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionErrorTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ExpressionTemplateParser{
|
||||
|
||||
private final ImmutableMap<Token, Operator> operators;
|
||||
private final ImmutableList<ValueReader> valueReaders;
|
||||
|
||||
public ExpressionTemplateParser(ImmutableMap<Token, Operator> operators, ImmutableList<ValueReader> valueReaders){
|
||||
this.operators = operators;
|
||||
this.valueReaders = valueReaders;
|
||||
}
|
||||
|
||||
public ExpressionTemplate parse(List<Token> tokenList){
|
||||
List<ExpressionTemplate> parts = new ArrayList<>();
|
||||
List<Operator> operators = new ArrayList<>();
|
||||
|
||||
try{
|
||||
parts.add(read(tokenList));
|
||||
}catch(IllegalArgumentException ex){
|
||||
return ExpressionErrorTemplate.of(ex.getMessage());
|
||||
}
|
||||
|
||||
while(!tokenList.isEmpty()){
|
||||
Token token = tokenList.remove(0);
|
||||
Operator operator = this.operators.get(token);
|
||||
if(operator == null){
|
||||
return ExpressionErrorTemplate.of("Error while parsing Expression. Got \"" + token + "\" but expected OPERATOR.");
|
||||
}
|
||||
|
||||
operators.add(operator);
|
||||
if(tokenList.isEmpty()){
|
||||
return ExpressionErrorTemplate.of("Received unexpected end of input.");
|
||||
}
|
||||
|
||||
try{
|
||||
parts.add(read(tokenList));
|
||||
}catch(IllegalArgumentException ex){
|
||||
return ExpressionErrorTemplate.of(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
while(!operators.isEmpty()){
|
||||
Operator operator = operators.get(0);
|
||||
int lowest = operator.getPriority();
|
||||
int start = 0;
|
||||
int end = 1;
|
||||
for(int i = 1; i < operators.size(); i++){
|
||||
operator = operators.get(i);
|
||||
if(operator.getPriority() < lowest){
|
||||
lowest = operator.getPriority();
|
||||
start = i;
|
||||
end = i + 1;
|
||||
}else
|
||||
if(operator.getPriority() > lowest){
|
||||
break;
|
||||
}else{
|
||||
end++;
|
||||
}
|
||||
}
|
||||
|
||||
operator = operators.get(start);
|
||||
|
||||
ExpressionTemplate replacement;
|
||||
if(start + 1 == end){
|
||||
replacement = operator.createTemplate(parts.get(start), parts.get(end));
|
||||
}else
|
||||
if(operator instanceof ListOperator listOperator){
|
||||
replacement = listOperator.createTemplate(new ArrayList<>(parts.subList(start, end + 1)));
|
||||
}else{
|
||||
List<ExpressionTemplate> conditions = new ArrayList<>(end - start);
|
||||
for(int i = start; i < end; i++)
|
||||
conditions.add(operators.get(i).createTemplate(parts.get(i), parts.get(i + 1)));
|
||||
|
||||
replacement = ExpressionTemplates.and(conditions);
|
||||
}
|
||||
|
||||
for(int i = start; i < end; i++){
|
||||
parts.remove(start);
|
||||
operators.remove(start);
|
||||
}
|
||||
parts.set(start, replacement);
|
||||
}
|
||||
|
||||
return parts.get(0);
|
||||
}
|
||||
|
||||
ExpressionTemplate read(List<Token> tokenList){
|
||||
for(ValueReader valueReader : valueReaders){
|
||||
ExpressionTemplate template = valueReader.read(this, tokenList);
|
||||
if(template != null)
|
||||
return template;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid Expression. Expected literal but got token \"" + tokenList.get(0).toString() + "\"");
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NegatedExpressionReader extends ValueReader{
|
||||
|
||||
private final Token tokenNegation;
|
||||
|
||||
public NegatedExpressionReader(Token tokenNegation){
|
||||
this.tokenNegation = tokenNegation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
if(tokenList.get(0) == tokenNegation){
|
||||
tokenList.remove(0);
|
||||
return ExpressionTemplates.negate(parser.read(tokenList));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NegatedNumberReader extends ValueReader{
|
||||
|
||||
private final Token tokenNegation;
|
||||
|
||||
public NegatedNumberReader(Token tokenNegation){
|
||||
this.tokenNegation = tokenNegation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
if(tokenList.get(0) == tokenNegation){
|
||||
tokenList.remove(0);
|
||||
return ExpressionTemplates.negateNumber(parser.read(tokenList));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ConstantExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.NumberToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NumberConstantReader extends ValueReader{
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
if(tokenList.get(0) instanceof NumberToken){
|
||||
return ConstantExpressionTemplate.of(((NumberToken)tokenList.remove(0)).getValue());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ParenthesisedExpressionReader extends ValueReader{
|
||||
|
||||
private final Token openingParenthesis;
|
||||
private final Token closingParenthesis;
|
||||
|
||||
public ParenthesisedExpressionReader(Token openingParenthesis, Token closingParenthesis){
|
||||
this.openingParenthesis = openingParenthesis;
|
||||
this.closingParenthesis = closingParenthesis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
if(tokenList.get(0) == openingParenthesis){
|
||||
int index = 0;
|
||||
int cnt = 1;
|
||||
do {
|
||||
index += 1;
|
||||
if(tokenList.size() <= index)
|
||||
return null;
|
||||
|
||||
Token token = tokenList.get(index);
|
||||
if(token == openingParenthesis){
|
||||
cnt++;
|
||||
}else
|
||||
if(token == closingParenthesis){
|
||||
cnt--;
|
||||
}
|
||||
}while(cnt != 0);
|
||||
|
||||
ExpressionTemplate result = parser.parse(new ArrayList<>(tokenList.subList(1, index)));
|
||||
tokenList.subList(0, index + 1).clear();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.PlaceholderToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PlaceholderReader extends ValueReader{
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
if(tokenList.get(0) instanceof PlaceholderToken){
|
||||
PlaceholderToken token = (PlaceholderToken)tokenList.remove(0);
|
||||
return token.getValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ConstantExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.StringToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class StringConstantReader extends ValueReader{
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
if(tokenList.get(0) instanceof StringToken){
|
||||
return ConstantExpressionTemplate.of(((StringToken)tokenList.remove(0)).getValue());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+10
-13
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,17 +23,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.bukkit;
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.bukkit.objects.WorldCache;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
/*
|
||||
* Small convenience class to "merge" the PluginCore and JavaPlugin classes.
|
||||
* Allows me to have BukkitCore<?> for whenever I also need a JavaPlugin (i.e. registering events).
|
||||
* See JoinEvent class for an example.
|
||||
*/
|
||||
public abstract class BukkitCore<F> extends JavaPlugin implements PluginCore<F>{
|
||||
public abstract WorldCache getWorldCache();
|
||||
}
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ValueReader{
|
||||
|
||||
public abstract ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList);
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.placeholders;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
|
||||
public interface Placeholder extends ExpressionTemplate{
|
||||
|
||||
static LiteralPlaceholderValue of(String value){
|
||||
return new LiteralPlaceholderValue(value);
|
||||
}
|
||||
|
||||
class LiteralPlaceholderValue implements Placeholder{
|
||||
|
||||
private final String value;
|
||||
|
||||
public LiteralPlaceholderValue(String value){
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToStringExpression instantiateWithStringResult(){
|
||||
return ToStringExpression.literal(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToDoubleExpression instantiateWithDoubleResult(){
|
||||
return ToDoubleExpression.literal(value.length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return ToBooleanExpression.literal(Boolean.parseBoolean(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.placeholders;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.AdvancedServerListAPI;
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
|
||||
import java.text.ParsePosition;
|
||||
|
||||
public class PlaceholderParser{
|
||||
|
||||
public static Placeholder parse(String text, ParsePosition position, GenericPlayer player, GenericServer server){
|
||||
AdvancedServerListAPI api = AdvancedServerListAPI.get();
|
||||
int index = position.getIndex();
|
||||
|
||||
StringBuilder identifier = new StringBuilder();
|
||||
StringBuilder values = new StringBuilder();
|
||||
|
||||
boolean identified = false;
|
||||
boolean invalid = true;
|
||||
|
||||
char[] chars = text.substring(index).toCharArray();
|
||||
for(final char c : chars){
|
||||
index++;
|
||||
if(c == '}'){
|
||||
invalid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(c == ' ' && !identified){
|
||||
identified = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(identified){
|
||||
values.append(c);
|
||||
}else{
|
||||
identifier.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
String identifierStr = identifier.toString();
|
||||
String valuesStr = values.toString();
|
||||
|
||||
StringBuilder raw = new StringBuilder();
|
||||
|
||||
position.setIndex(index + 1);
|
||||
|
||||
if(invalid){
|
||||
raw.append("${").append(identifierStr);
|
||||
|
||||
if(identified)
|
||||
raw.append(' ').append(valuesStr);
|
||||
|
||||
|
||||
return Placeholder.of(raw.toString());
|
||||
}
|
||||
|
||||
PlaceholderProvider provider = api.retrievePlaceholderProvider(identifierStr);
|
||||
if(provider == null){
|
||||
raw.append("${").append(identifierStr);
|
||||
|
||||
if(identified)
|
||||
raw.append(' ').append(valuesStr);
|
||||
|
||||
|
||||
raw.append('}');
|
||||
|
||||
return Placeholder.of(raw.toString());
|
||||
}
|
||||
|
||||
String replacement = provider.parsePlaceholder(valuesStr, player, server);
|
||||
if(replacement == null){
|
||||
raw.append("${").append(identifierStr);
|
||||
|
||||
if(identified)
|
||||
raw.append(' ').append(valuesStr);
|
||||
|
||||
raw.append('}');
|
||||
|
||||
return Placeholder.of(raw.toString());
|
||||
}
|
||||
|
||||
return Placeholder.of(replacement);
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
|
||||
|
||||
public abstract class AbstractBinaryToBooleanExpression<T extends Expression> implements ToBooleanExpression{
|
||||
|
||||
protected final T a;
|
||||
protected final T b;
|
||||
|
||||
public AbstractBinaryToBooleanExpression(T a, T b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
|
||||
|
||||
public abstract class AbstractBinaryToDoubleExpression<T extends Expression> implements ToDoubleExpression{
|
||||
|
||||
protected final T a;
|
||||
protected final T b;
|
||||
|
||||
public AbstractBinaryToDoubleExpression(T a, T b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.Conversions;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
|
||||
|
||||
public abstract class AbstractBooleanExpressionTemplate implements ExpressionTemplate{
|
||||
|
||||
@Override
|
||||
public ToStringExpression instantiateWithStringResult(){
|
||||
return Conversions.toString(instantiateWithBooleanResult());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToDoubleExpression instantiateWithDoubleResult(){
|
||||
return Conversions.toDouble(instantiateWithBooleanResult());
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.Conversions;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
|
||||
|
||||
public abstract class AbstractDoubleExpressionTemplate implements ExpressionTemplate{
|
||||
|
||||
@Override
|
||||
public ToStringExpression instantiateWithStringResult(){
|
||||
return Conversions.toString(instantiateWithDoubleResult());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Conversions.toBoolean(instantiateWithDoubleResult());
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.Conversions;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
|
||||
|
||||
public abstract class AbstractStringExpressionTemplate implements ExpressionTemplate{
|
||||
|
||||
@Override
|
||||
public ToDoubleExpression instantiateWithDoubleResult(){
|
||||
return Conversions.toDouble(instantiateWithStringResult());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Conversions.toBoolean(instantiateWithStringResult());
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public abstract class AbstractToBooleanExpression<T extends Expression> implements ToBooleanExpression{
|
||||
|
||||
protected final Collection<T> operands;
|
||||
|
||||
public AbstractToBooleanExpression(Collection<T> operands){
|
||||
this.operands = operands;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public abstract class AbstractToDoubleExpression<T extends Expression> implements ToDoubleExpression{
|
||||
|
||||
protected final Collection<T> operands;
|
||||
|
||||
public AbstractToDoubleExpression(Collection<T> operands){
|
||||
this.operands = operands;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public abstract class AbstractToStringExpression<T extends Expression> implements ToStringExpression{
|
||||
|
||||
protected Collection<T> operands;
|
||||
|
||||
public AbstractToStringExpression(Collection<T> operands){
|
||||
this.operands = operands;
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
|
||||
|
||||
public abstract class AbstractUnaryToBooleanExpression<T extends Expression> implements ToBooleanExpression{
|
||||
|
||||
protected final T delegate;
|
||||
|
||||
public AbstractUnaryToBooleanExpression(T delegate){
|
||||
this.delegate = delegate;
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
|
||||
|
||||
public abstract class AbstractUnaryToDoubleExpression<T extends Expression> implements ToDoubleExpression{
|
||||
|
||||
protected final T delegate;
|
||||
|
||||
public AbstractUnaryToDoubleExpression(T delegate){
|
||||
this.delegate = delegate;
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
|
||||
|
||||
public abstract class AbstractUnaryToStringExpression<T extends Expression> implements ToStringExpression{
|
||||
|
||||
protected final T delegate;
|
||||
|
||||
public AbstractUnaryToStringExpression(T delegate){
|
||||
this.delegate = delegate;
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
|
||||
|
||||
public class ConstantExpressionTemplate implements ExpressionTemplate{
|
||||
|
||||
private final ToStringExpression stringExpression;
|
||||
private final ToDoubleExpression doubleExpression;
|
||||
private final ToBooleanExpression booleanExpression;
|
||||
|
||||
private ConstantExpressionTemplate(String stringValue, double doubleValue, boolean booleanValue){
|
||||
this.stringExpression = ToStringExpression.literal(stringValue);
|
||||
this.doubleExpression = ToDoubleExpression.literal(doubleValue);
|
||||
this.booleanExpression = ToBooleanExpression.literal(booleanValue);
|
||||
}
|
||||
|
||||
public static ConstantExpressionTemplate of(String stringValue){
|
||||
double doubleValue;
|
||||
try{
|
||||
doubleValue = Double.parseDouble(stringValue);
|
||||
}catch(NumberFormatException ex){
|
||||
doubleValue = stringValue.length();
|
||||
}
|
||||
return new ConstantExpressionTemplate(stringValue, doubleValue, Boolean.parseBoolean(stringValue));
|
||||
}
|
||||
|
||||
public static ConstantExpressionTemplate of(double doubleValue){
|
||||
return new ConstantExpressionTemplate(((int)doubleValue) == doubleValue ? Integer.toString((int)doubleValue) : Double.toString(doubleValue), doubleValue, doubleValue != 0);
|
||||
}
|
||||
|
||||
public static ConstantExpressionTemplate of(boolean booleanValue){
|
||||
return new ConstantExpressionTemplate(Boolean.toString(booleanValue), booleanValue ? 1 : 0, booleanValue);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ToStringExpression instantiateWithStringResult(){
|
||||
return stringExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToDoubleExpression instantiateWithDoubleResult(){
|
||||
return doubleExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return booleanExpression;
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
|
||||
|
||||
public class ExpressionErrorTemplate implements ExpressionTemplate{
|
||||
|
||||
private final String msg;
|
||||
|
||||
private ExpressionErrorTemplate(String msg){
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public static ExpressionErrorTemplate of(String msg){
|
||||
return new ExpressionErrorTemplate(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToStringExpression instantiateWithStringResult(){
|
||||
return ToStringExpression.literal(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToDoubleExpression instantiateWithDoubleResult(){
|
||||
return ToDoubleExpression.literal(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return ToBooleanExpression.literal(false);
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
|
||||
|
||||
public interface ExpressionTemplate{
|
||||
|
||||
ToStringExpression instantiateWithStringResult();
|
||||
|
||||
ToDoubleExpression instantiateWithDoubleResult();
|
||||
|
||||
ToBooleanExpression instantiateWithBooleanResult();
|
||||
}
|
||||
+422
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.Expressions;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class ExpressionTemplates{
|
||||
|
||||
public static ExpressionTemplate negate(ExpressionTemplate template){
|
||||
return new Negation(template);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate and(Collection<ExpressionTemplate> operands){
|
||||
return new And(operands);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate or(Collection<ExpressionTemplate> operands){
|
||||
return new Or(operands);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate concat(Collection<ExpressionTemplate> operands){
|
||||
return new Concatenate(operands);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate equal(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new Equal(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate notEqual(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new NotEqual(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate equalIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new EqualIgnoreCase(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate notEqualIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new NotEqualIgnoreCase(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate startsWith(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new StartsWith(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate endsWith(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new EndsWith(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate contains(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new Contains(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate greater(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new Greater(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate greaterOrEqual(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new GreaterOrEqual(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate less(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new Less(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate lessOrEqual(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new LessOrEqual(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate sum(Collection<ExpressionTemplate> operands){
|
||||
return new Sum(operands);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate product(Collection<ExpressionTemplate> operands){
|
||||
return new Product(operands);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate sub(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new Sub(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate div(ExpressionTemplate a, ExpressionTemplate b){
|
||||
return new Div(a, b);
|
||||
}
|
||||
|
||||
public static ExpressionTemplate negateNumber(ExpressionTemplate template){
|
||||
return new NegationNumber(template);
|
||||
}
|
||||
|
||||
private static class Negation extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate template;
|
||||
|
||||
Negation(ExpressionTemplate template){
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.negate(template.instantiateWithBooleanResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class And extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final Collection<ExpressionTemplate> operands;
|
||||
|
||||
And(Collection<ExpressionTemplate> operands){
|
||||
this.operands = operands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.and(operands.stream().map(ExpressionTemplate::instantiateWithBooleanResult).toList());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Or extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final Collection<ExpressionTemplate> operands;
|
||||
|
||||
Or(Collection<ExpressionTemplate> operands){
|
||||
this.operands = operands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.or(operands.stream().map(ExpressionTemplate::instantiateWithBooleanResult).toList());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Concatenate extends AbstractStringExpressionTemplate{
|
||||
|
||||
private final Collection<ExpressionTemplate> operands;
|
||||
|
||||
Concatenate(Collection<ExpressionTemplate> operands){
|
||||
this.operands = operands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToStringExpression instantiateWithStringResult(){
|
||||
return Expressions.concat(operands.stream().map(ExpressionTemplate::instantiateWithStringResult).toList());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Equal extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
Equal(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.equal(a.instantiateWithStringResult(), b.instantiateWithStringResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class NotEqual extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
NotEqual(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.notEqual(a.instantiateWithStringResult(), b.instantiateWithStringResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class EqualIgnoreCase extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
EqualIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.equalIgnoreCase(a.instantiateWithStringResult(), b.instantiateWithStringResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class NotEqualIgnoreCase extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
NotEqualIgnoreCase(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.notEqualIgnoreCase(a.instantiateWithStringResult(), b.instantiateWithStringResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class StartsWith extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
private StartsWith(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.startsWith(a.instantiateWithStringResult(), b.instantiateWithStringResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class EndsWith extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
private EndsWith(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.endsWith(a.instantiateWithStringResult(), b.instantiateWithStringResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Contains extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
private Contains(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.contains(a.instantiateWithStringResult(), b.instantiateWithStringResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Greater extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
Greater(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.greaterThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class GreaterOrEqual extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
GreaterOrEqual(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.greaterOrEqualThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Less extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
Less(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.lessThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class LessOrEqual extends AbstractBooleanExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
LessOrEqual(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return Expressions.lessOrEqualThan(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Sum extends AbstractDoubleExpressionTemplate{
|
||||
|
||||
private final Collection<ExpressionTemplate> operands;
|
||||
|
||||
Sum(Collection<ExpressionTemplate> operands){
|
||||
this.operands = operands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToDoubleExpression instantiateWithDoubleResult(){
|
||||
return Expressions.sum(operands.stream().map(ExpressionTemplate::instantiateWithDoubleResult).toList());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Product extends AbstractDoubleExpressionTemplate{
|
||||
|
||||
private final Collection<ExpressionTemplate> operands;
|
||||
|
||||
Product(Collection<ExpressionTemplate> operands){
|
||||
this.operands = operands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToDoubleExpression instantiateWithDoubleResult(){
|
||||
return Expressions.product(operands.stream().map(ExpressionTemplate::instantiateWithDoubleResult).toList());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Sub extends AbstractDoubleExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
Sub(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToDoubleExpression instantiateWithDoubleResult(){
|
||||
return Expressions.sub(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Div extends AbstractDoubleExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate a;
|
||||
private final ExpressionTemplate b;
|
||||
|
||||
Div(ExpressionTemplate a, ExpressionTemplate b){
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToDoubleExpression instantiateWithDoubleResult(){
|
||||
return Expressions.div(a.instantiateWithDoubleResult(), b.instantiateWithDoubleResult());
|
||||
}
|
||||
}
|
||||
|
||||
private static class NegationNumber extends AbstractDoubleExpressionTemplate{
|
||||
|
||||
private final ExpressionTemplate template;
|
||||
|
||||
NegationNumber(ExpressionTemplate template){
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToDoubleExpression instantiateWithDoubleResult(){
|
||||
return Expressions.negateNumber(template.instantiateWithDoubleResult());
|
||||
}
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens;
|
||||
|
||||
public class BooleanToken extends Token{
|
||||
|
||||
public static final BooleanToken TRUE = new BooleanToken(true);
|
||||
public static final BooleanToken FALSE = new BooleanToken(false);
|
||||
private final boolean value;
|
||||
|
||||
public BooleanToken(boolean value){
|
||||
super("BOOLEAN(" + value + ")");
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean getValue(){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens;
|
||||
|
||||
public class DefaultTokens{
|
||||
public static final Token AND = new Token("AND");
|
||||
public static final Token OR = new Token("OR");
|
||||
public static final Token OPENING_PARENTHESIS = new Token("OPENING_PARENTHESIS");
|
||||
public static final Token CLOSING_PARENTHESIS = new Token("CLOSING_PARENTHESIS");
|
||||
public static final Token EQUAL = new Token("EQUAL");
|
||||
public static final Token NOT_EQUAL = new Token("NOT_EQUAL");
|
||||
public static final Token EQUAL_IGNORE_CASE = new Token("EQUAL_IGNORE_CASE");
|
||||
public static final Token NOT_EQUAL_IGNORE_CASE = new Token("NOT_EQUAL_IGNORE_CASE");
|
||||
public static final Token STARTS_WITH = new Token("STARTS_WITH");
|
||||
public static final Token ENDS_WITH = new Token("ENDS_WITH");
|
||||
public static final Token CONTAINS = new Token("CONTAINS");
|
||||
public static final Token NEGATION = new Token("NEGATION");
|
||||
public static final Token GREATER_THAN = new Token("GREATER_THAN");
|
||||
public static final Token GREATER_OR_EQUAL_THAN = new Token("GREATER_OR_EQUAL_THAN");
|
||||
public static final Token LESSER_THAN = new Token("LESSER_THAN");
|
||||
public static final Token LESSER_OR_EQUAL_THAN = new Token("LESSER_OR_EQUAL_THAN");
|
||||
public static final Token CONCAT_STRING = new Token("CONCAT_STRING");
|
||||
public static final Token ADD = new Token("ADD");
|
||||
public static final Token SUB = new Token("SUB");
|
||||
public static final Token MULT = new Token("MULT");
|
||||
public static final Token DIV = new Token("DIV");
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens;
|
||||
|
||||
public class NumberToken extends Token{
|
||||
|
||||
private final double value;
|
||||
|
||||
public NumberToken(double value){
|
||||
super("NUMBER(" + value + ")");
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public double getValue(){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.Placeholder;
|
||||
|
||||
public class PlaceholderToken extends Token{
|
||||
|
||||
private final Placeholder value;
|
||||
|
||||
public PlaceholderToken(Placeholder value){
|
||||
super("PLACEHOLDER");
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Placeholder getValue(){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens;
|
||||
|
||||
public class StringToken extends Token{
|
||||
|
||||
private final String value;
|
||||
|
||||
public StringToken(String value){
|
||||
super("STRING(" + value + ")");
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue(){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
+11
-4
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,11 +23,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.versionuploader.hangar.version;
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens;
|
||||
|
||||
public record Namespace(String owner, String slug){
|
||||
public class Token{
|
||||
|
||||
private final String id;
|
||||
|
||||
public Token(String id){
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return owner() + "/" + slug();
|
||||
return id;
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.StringToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.text.ParsePosition;
|
||||
|
||||
public class NonQuotedLiteralTokenReader extends TokenReader{
|
||||
|
||||
public NonQuotedLiteralTokenReader(int priority){
|
||||
super(priority);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
|
||||
int startIndex = position.getIndex();
|
||||
int index = position.getIndex();
|
||||
|
||||
while(++index < text.length() && !Character.isWhitespace(text.charAt(index)))
|
||||
;
|
||||
|
||||
position.setIndex(index);
|
||||
|
||||
return new StringToken(text.substring(startIndex, position.getIndex()));
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.NumberToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Locale;
|
||||
|
||||
public class NumberTokenReader extends TokenReader{
|
||||
|
||||
private final NumberFormat format = NumberFormat.getInstance(Locale.ROOT);
|
||||
|
||||
public NumberTokenReader(int priority){
|
||||
super(priority);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
|
||||
int previous = position.getIndex();
|
||||
Number number = format.parse(text, position);
|
||||
|
||||
if(position.getIndex() != previous)
|
||||
return new NumberToken(number.doubleValue());
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.text.ParsePosition;
|
||||
|
||||
public class PatternTokenReader extends TokenReader{
|
||||
|
||||
private final Token token;
|
||||
private final String pattern;
|
||||
private final boolean ignoreCase;
|
||||
|
||||
public PatternTokenReader(Token token, String pattern){
|
||||
this(token, pattern, true);
|
||||
}
|
||||
|
||||
public PatternTokenReader(Token token, String pattern, boolean ignoreCase){
|
||||
super(pattern.length());
|
||||
|
||||
this.token = token;
|
||||
this.pattern = pattern;
|
||||
this.ignoreCase = ignoreCase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
|
||||
if(text.regionMatches(ignoreCase, position.getIndex(), pattern, 0, pattern.length())){
|
||||
position.setIndex(position.getIndex() + pattern.length());
|
||||
return token;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.PlaceholderParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.PlaceholderToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.text.ParsePosition;
|
||||
|
||||
public class PlaceholderTokenReader extends TokenReader{
|
||||
|
||||
public PlaceholderTokenReader(int priority){
|
||||
super(priority);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
|
||||
if(position.getIndex() + 1 < text.length() && text.charAt(position.getIndex()) == '$' && text.charAt(position.getIndex() + 1) == '{'){
|
||||
position.setIndex(position.getIndex() + 2);
|
||||
return new PlaceholderToken(PlaceholderParser.parse(text, position, player, server));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.StringToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.text.ParsePosition;
|
||||
|
||||
public class QuotedLiteralTokenReader extends TokenReader{
|
||||
|
||||
private final char quote;
|
||||
|
||||
public QuotedLiteralTokenReader(int priority, char quote){
|
||||
super(priority);
|
||||
|
||||
this.quote = quote;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
|
||||
if(position.getIndex() < text.length() && text.charAt(position.getIndex()) == quote){
|
||||
int startIndex = position.getIndex();
|
||||
|
||||
position.setIndex(position.getIndex() + 1);
|
||||
|
||||
while(position.getIndex() < text.length() && quote != text.charAt(position.getIndex()))
|
||||
position.setIndex(position.getIndex() + 1);
|
||||
|
||||
position.setIndex(position.getIndex() + 1);
|
||||
|
||||
return new StringToken(text.substring(startIndex + 1, position.getIndex() - 1));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.text.ParsePosition;
|
||||
|
||||
public abstract class TokenReader{
|
||||
|
||||
private final int priority;
|
||||
|
||||
public TokenReader(int priority){
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public int getPriority(){
|
||||
return priority;
|
||||
}
|
||||
|
||||
public abstract Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server);
|
||||
}
|
||||
+24
-1
@@ -70,21 +70,34 @@ public class FaviconHandler<F>{
|
||||
|
||||
private CompletableFuture<F> convert(String input, Function<BufferedImage, F> function){
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Getting BufferedImage for input '%s'...", input);
|
||||
|
||||
BufferedImage img = resolveImage(core, input);
|
||||
if(img == null)
|
||||
if(img == null){
|
||||
core.getPlugin().getPluginLogger().debugWarn(FaviconHandler.class, "No BufferedImage could be created!");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Received BufferedImage! Applying it...");
|
||||
|
||||
return function.apply(img);
|
||||
}, faviconThreadPool);
|
||||
}
|
||||
|
||||
private BufferedImage resolveImage(AdvancedServerList<F> core, String input){
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resolving favicon for input '%s'...", input);
|
||||
|
||||
InputStream stream;
|
||||
|
||||
if(input.toLowerCase(Locale.ROOT).startsWith("https://")){
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "URL detected. Getting file from it...");
|
||||
|
||||
stream = getFromUrl(core, input);
|
||||
}else
|
||||
if(input.toLowerCase(Locale.ROOT).endsWith(".png")){
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Image file detected. Trying to reolve it...");
|
||||
|
||||
File folder = core.getPlugin().getFolderPath().resolve("favicons").toFile();
|
||||
if(!folder.exists()){
|
||||
core.getPlugin().getPluginLogger().warn("Cannot get Favicon %s from favicons folder. Folder doesn't exist!", input);
|
||||
@@ -95,12 +108,16 @@ public class FaviconHandler<F>{
|
||||
|
||||
try{
|
||||
stream = new FileInputStream(file);
|
||||
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resolved image file!");
|
||||
}catch(IOException ex){
|
||||
core.getPlugin().getPluginLogger().warn("Cannot create Favicon from File %s.", input);
|
||||
core.getPlugin().getPluginLogger().warn("Cause: %s", ex.getMessage());
|
||||
return null;
|
||||
}
|
||||
}else{
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Possible player name/UUID detected. Using https://mc-heads.net/avatar/%s/64...", input);
|
||||
|
||||
stream = getFromUrl(core, "https://mc-heads.net/avatar/" + input + "/64");
|
||||
}
|
||||
|
||||
@@ -116,6 +133,8 @@ public class FaviconHandler<F>{
|
||||
return null;
|
||||
}
|
||||
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resizing image to 64x64 pixels...");
|
||||
|
||||
BufferedImage favicon = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D img = favicon.createGraphics();
|
||||
|
||||
@@ -123,6 +142,7 @@ public class FaviconHandler<F>{
|
||||
img.drawImage(original, 0, 0, 64, 64, null);
|
||||
img.dispose();
|
||||
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Image resized!");
|
||||
return favicon;
|
||||
}catch(IOException ex){
|
||||
core.getPlugin().getPluginLogger().warn("Unable to create Favicon. Encountered IOException during creation.");
|
||||
@@ -133,11 +153,14 @@ public class FaviconHandler<F>{
|
||||
|
||||
private InputStream getFromUrl(AdvancedServerList<F> core, String url){
|
||||
try{
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resolving URL '%s'...", url);
|
||||
|
||||
URL faviconUrl = new URL(url);
|
||||
URLConnection connection = faviconUrl.openConnection();
|
||||
connection.setRequestProperty("User-Agent", "AdvancedServerList/" + core.getVersion());
|
||||
connection.connect();
|
||||
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "URL resolved!");
|
||||
return connection.getInputStream();
|
||||
}catch(IOException ex){
|
||||
core.getPlugin().getPluginLogger().warn("Error while connecting to %s for Favicon creation.", url);
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ public class ProfileManager{
|
||||
if(profile.isInvalidProfile())
|
||||
continue;
|
||||
|
||||
if(profile.evalConditions(player, server))
|
||||
if(profile.evalConditions(core.getExpressionEngine(), core.getPlugin().getPluginLogger(), player, server))
|
||||
return profile;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,10 +31,21 @@ disableCache: false
|
||||
#
|
||||
checkUpdates: true
|
||||
|
||||
#
|
||||
# Should debug mode be enabled?
|
||||
#
|
||||
# When set to true will AdvancedServerList print additional messages to the console prefixed with "[DEBUG]".
|
||||
# It is recommended to only enable this when having problems or when being told to by the plugin dev, as it could
|
||||
# otherwise cause significant spam in your console.
|
||||
#
|
||||
# Defaults to false when not present.
|
||||
#
|
||||
debug: false
|
||||
|
||||
#
|
||||
# DO NOT EDIT!
|
||||
#
|
||||
# This is used internally to determine if the config needs to be migrated.
|
||||
# Changing or even removing this option could result in your config being broken.
|
||||
#
|
||||
config-version: 2
|
||||
config-version: ${plugin.config.version}
|
||||
@@ -6,6 +6,15 @@
|
||||
#
|
||||
priority: 0
|
||||
|
||||
#
|
||||
# Set conditions that need to me met to show this profile.
|
||||
# You can use keywords 'and' or 'or' (Or alternatively '&&' or `||`) to make more complex condition sets.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#condition
|
||||
#
|
||||
# condition: '${player protocol} < 759'
|
||||
#
|
||||
|
||||
#
|
||||
# Set conditions that needs to be met.
|
||||
# Only when all conditions return true will the profile be shown (Given no profile with higher priority is used).
|
||||
|
||||
@@ -23,4 +23,5 @@
|
||||
#
|
||||
#
|
||||
|
||||
version=${plugin.version}
|
||||
version=${plugin.version}
|
||||
config-version=${plugin.config.version}
|
||||
+26
-18
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,30 +23,38 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot.commands;
|
||||
package ch.andre601.advancedserverlist.test;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.commands.CmdSender;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
|
||||
public class SpigotCmdSender implements CmdSender{
|
||||
|
||||
private final CommandSender sender;
|
||||
private final BukkitAudiences bukkitAudiences;
|
||||
|
||||
public SpigotCmdSender(CommandSender sender, BukkitAudiences bukkitAudiences){
|
||||
this.sender = sender;
|
||||
this.bukkitAudiences = bukkitAudiences;
|
||||
public class DummyPluginLogger implements PluginLogger{
|
||||
@Override
|
||||
public void debug(Class<?> clazz, String msg, Object... args){
|
||||
info("[DEBUG] [" + clazz.getSimpleName() + "] " + msg, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission){
|
||||
return sender.hasPermission(permission) || sender.hasPermission("advancedserverlist.admin");
|
||||
public void debugWarn(Class<?> clazz, String msg, Object... args){
|
||||
warn("[DEBUG] [" + clazz.getSimpleName() + "] " + msg, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMsg(String msg, Object... args){
|
||||
bukkitAudiences.sender(sender).sendMessage(ComponentParser.text(String.format(msg, args)).toComponent());
|
||||
public void info(String msg, Object... args){
|
||||
System.out.printf((msg) + "%n", args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Object... args){
|
||||
System.out.printf((msg) + "%n", args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable){
|
||||
System.out.printf((msg) + "%n", throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable, Object... args){
|
||||
System.out.printf((msg) + "%n", args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.test;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionEngine;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class ExpressionParserTests{
|
||||
|
||||
private final ExpressionEngine expressionEngine = new ExpressionEngine();
|
||||
private final DummyPluginLogger logger = new DummyPluginLogger();
|
||||
private final Map<String, Boolean> testValuesMap = getTestMap();
|
||||
|
||||
@Test
|
||||
public void testBasicExpressionResults(){
|
||||
for(Map.Entry<String, Boolean> values : testValuesMap.entrySet()){
|
||||
logger.info("TEST[expression=\"%s\", expected=%b]", values.getKey(), values.getValue());
|
||||
|
||||
boolean result = expressionEngine.compile(values.getKey(), logger, null, null).instantiateWithBooleanResult().evaluate();
|
||||
logger.info("Result (output, isExpected): " + result + ", " + (result == values.getValue()));
|
||||
assertEquals(result, values.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Boolean> getTestMap(){
|
||||
return Map.of(
|
||||
"20 > 10", true,
|
||||
"10 > 20", false,
|
||||
"10 = 10", true,
|
||||
"10 = 20", false,
|
||||
"(10 - 5) > (1 + 1)", true,
|
||||
"(10 - 10) > (1 + 1)", false,
|
||||
"100 > 50 and 50 < 100", true,
|
||||
"100 < 50 and 50 > 100", false,
|
||||
"true or 100 > 10", true,
|
||||
"false or 100 < 10", false
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,9 @@
|
||||
package ch.andre601.advancedserverlist.test;
|
||||
|
||||
import com.unascribed.flexver.FlexVerComparator;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class FlexVerTests{
|
||||
|
||||
@@ -286,7 +288,9 @@ public class FlexVerTests{
|
||||
|
||||
private void compare(String version1, String comparator, String version2, int expected){
|
||||
String expression = version1 + " " + comparator + " " + version2 + "?";
|
||||
int result = FlexVerComparator.compare(version1, version2);
|
||||
|
||||
System.out.printf("│ %-24s %5b │\n", expression, FlexVerComparator.compare(version1, version2) == expected);
|
||||
assertEquals(result, expected);
|
||||
}
|
||||
}
|
||||
+17
-17
@@ -25,18 +25,19 @@ def on_page_markdown(
|
||||
def replace(match: Match):
|
||||
type, args = match.groups()
|
||||
args = args.strip()
|
||||
if type == "abstract": return _admo(text = args, type = "abstract")
|
||||
elif type == "info": return _admo(text = args, type = "info")
|
||||
elif type == "tip": return _admo(text = args, type = "tip")
|
||||
elif type == "success": return _admo(text = args, type = "success")
|
||||
elif type == "question": return _admo(text = args, type = "question")
|
||||
elif type == "warning": return _admo(text = args, type = "warning")
|
||||
elif type == "failure": return _admo(text = args, type = "failure")
|
||||
elif type == "danger": return _admo(text = args, type = "danger")
|
||||
elif type == "bug": return _admo(text = args, type = "bug")
|
||||
elif type == "example": return _admo(text = args, type = "example")
|
||||
elif type == "quote": return _admo(text = args, type = "quote")
|
||||
else: return _admo(text = args)
|
||||
if type == "abstract": return _admo(text = args, type = "abstract")
|
||||
elif type == "info": return _admo(text = args, type = "info")
|
||||
elif type == "tip": return _admo(text = args, type = "tip")
|
||||
elif type == "success": return _admo(text = args, type = "success")
|
||||
elif type == "question": return _admo(text = args, type = "question")
|
||||
elif type == "warning": return _admo(text = args, type = "warning")
|
||||
elif type == "failure": return _admo(text = args, type = "failure")
|
||||
elif type == "danger": return _admo(text = args, type = "danger")
|
||||
elif type == "bug": return _admo(text = args, type = "bug")
|
||||
elif type == "example": return _admo(text = args, type = "example")
|
||||
elif type == "quote": return _admo(text = args, type = "quote")
|
||||
elif type == "deprecated": return _admo(text = args, type = "deprecated")
|
||||
else: return _admo(text = args)
|
||||
|
||||
# Otherwise, raise an error
|
||||
raise RuntimeError(f"Unknown shortcode: {type}")
|
||||
@@ -48,11 +49,10 @@ def on_page_markdown(
|
||||
)
|
||||
|
||||
def _admo(text: str = "", type: str = ""):
|
||||
classes = f"mdx-badge mdx-badge--{type}" if type else "mdx-badge"
|
||||
iconClasses = f"mdx-badge__icon mdx-badge--{type}" if type else "mdx-badge__icon"
|
||||
classes = f"mdx-grid-wrapper mdx-admo--{type}" if type else "mdx-grid-wrapper"
|
||||
return "".join([
|
||||
f"<div class=\"{classes}\">",
|
||||
f"<span class=\"{iconClasses}\"></span>",
|
||||
*([f"<span class=\"mdx-badge__text\">{text}</span>"] if text else []),
|
||||
f"</div>",
|
||||
f"<div class=\"mdx-grid-child mdx-grid-child--icon\"></div>",
|
||||
f"<div class=\"mdx-grid-child\">{text}</div>"
|
||||
"</div>",
|
||||
])
|
||||
@@ -1,5 +1,6 @@
|
||||
nav:
|
||||
- Home: index.md
|
||||
- getting-started
|
||||
- commands
|
||||
- profiles
|
||||
- examples
|
||||
|
||||
+273
-243
@@ -11,76 +11,79 @@ It provides a way for your plugin to provide its own placeholders that should be
|
||||
|
||||
Add the following to your `pom.xml`, `build.gradle` or `build.gradle.kts` depending on what you use:
|
||||
|
||||
=== ":simple-apachemaven: Maven"
|
||||
/// tab | :simple-apachemaven: Maven
|
||||
```xml title="pom.xml"
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack</id>
|
||||
<url>https://jitpack.io/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>{apiVersion}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Optional platform dependencies -->
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-bukkit</artifactId>
|
||||
<version>{apiVersion}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-bungeecord</artifactId>
|
||||
<version>{apiVersion}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-velocity</artifactId>
|
||||
<version>{apiVersion}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
///
|
||||
|
||||
/// tab | :simple-gradle: Gradle
|
||||
```groovy title="build.gradle"
|
||||
repositorories {
|
||||
maven { url = 'https://jitpack.io/' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'ch.andre601.asl-api:api:{apiVersion}'
|
||||
|
||||
```xml title="pom.xml"
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack</id>
|
||||
<url>https://jitpack.io/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
// Optional platform dependencies
|
||||
compileOnly 'ch.andre601.asl-api:platform-bukkit:{apiVersion}'
|
||||
compileOnly 'ch.andre601.asl-api:platform-bungeecord:{apiVersion}'
|
||||
compileOnly 'ch.andre601.asl-api:platform-velocity:{apiVersion}'
|
||||
}
|
||||
```
|
||||
///
|
||||
|
||||
/// tab | :simple-gradle: Gradle (KTS)
|
||||
```kotlin title="build.gradle.kts"
|
||||
repositories {
|
||||
maven("https://jitpack.io")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("ch.andre601.asl-api:api:{apiVersion}")
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>{version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Optional platform dependencies -->
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-bukkit</artifactId>
|
||||
<version>{version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-bungeecord</artifactId>
|
||||
<version>{version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-velocity</artifactId>
|
||||
<version>{version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
=== ":simple-gradle: Gradle"
|
||||
|
||||
```groovy title="build.gradle"
|
||||
repositorories {
|
||||
maven { url = 'https://jitpack.io/' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly 'ch.andre601.asl-api:api:{version}'
|
||||
|
||||
// Optional platform dependencies
|
||||
compileOnly 'ch.andre601.asl-api:platform-bukkit:{version}'
|
||||
compileOnly 'ch.andre601.asl-api:platform-bungeecord:{version}'
|
||||
compileOnly 'ch.andre601.asl-api:platform-velocity:{version}'
|
||||
}
|
||||
```
|
||||
=== ":simple-gradle: Gradle (KTS)"
|
||||
```kotlin title="build.gradle.kts"
|
||||
repositories {
|
||||
maven("https://jitpack.io")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("ch.andre601.asl-api:api:{version}")
|
||||
|
||||
// Optional platform dependencies
|
||||
compileOnly("ch.andre601.asl-api:platform-bukkit:{version}")
|
||||
compileOnly("ch.andre601.asl-api:platform-bungeecord:{version}")
|
||||
compileOnly("ch.andre601.asl-api:platform-velocity:{version}")
|
||||
}
|
||||
```
|
||||
// Optional platform dependencies
|
||||
compileOnly("ch.andre601.asl-api:platform-bukkit:{apiVersion}")
|
||||
compileOnly("ch.andre601.asl-api:platform-bungeecord:{apiVersion}")
|
||||
compileOnly("ch.andre601.asl-api:platform-velocity:{apiVersion}")
|
||||
}
|
||||
```
|
||||
///
|
||||
|
||||
## Adding your own Placeholders
|
||||
|
||||
@@ -108,13 +111,14 @@ public class MyPlaceholders extends PlaceholderProvider {
|
||||
}
|
||||
```
|
||||
|
||||
!!! tip
|
||||
You can replace the Constructor with a String argument with a no-args constructor and set the identifier directly in the `super`:
|
||||
```java
|
||||
public MyPlaceholders() {
|
||||
super("myplaceholders");
|
||||
}
|
||||
```
|
||||
/// tip
|
||||
You can replace the Constructor with a String argument with a no-args constructor and set the identifier directly in the `super`:
|
||||
```java
|
||||
public MyPlaceholders() {
|
||||
super("myplaceholders");
|
||||
}
|
||||
```
|
||||
///
|
||||
|
||||
The [`parsePlaceholder(String, GenericPlayer, GenericServer)`][parseplaceholder] method is used by AdvancedServerList to replace a matching placeholder with a value.
|
||||
What you return is completely up to you. Just keep in mind that returning `null` will be treated as an invalid placeholder by AdvancedServerList, resulting in the placeholder being returned as-is without any changes.
|
||||
@@ -122,23 +126,26 @@ What you return is completely up to you. Just keep in mind that returning `null`
|
||||
[placeholderprovider]: reference/api/ch.andre601.advancedserverlist.api/placeholderprovider.md
|
||||
[parseplaceholder]: reference/api/ch.andre601.advancedserverlist.api/placeholderprovider.md#parseplaceholder(string,-genericplayer,-genericserver)
|
||||
|
||||
??? example "Example of final class"
|
||||
```java
|
||||
public class MyPlaceholders extends PlaceholderProvider {
|
||||
|
||||
public MyPlaceholders() {
|
||||
super("myplaceholders");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server) {
|
||||
if(placeholder.equalsIgnoreCase("hello"))
|
||||
return "Hello " + player.getName();
|
||||
|
||||
return null;
|
||||
}
|
||||
/// details | Example of final class
|
||||
type: example
|
||||
|
||||
```java
|
||||
public class MyPlaceholders extends PlaceholderProvider {
|
||||
|
||||
public MyPlaceholders() {
|
||||
super("myplaceholders");
|
||||
}
|
||||
```
|
||||
|
||||
@Override
|
||||
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server) {
|
||||
if(placeholder.equalsIgnoreCase("hello"))
|
||||
return "Hello " + player.getName();
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
///
|
||||
|
||||
### 2. Register the Placeholders
|
||||
|
||||
@@ -173,158 +180,181 @@ The final thing you should make sure is to define AdvancedServerList as a depend
|
||||
|
||||
Below are example setups for Spigot, Paper, BungeeCord and Velocity:
|
||||
|
||||
=== ":simple-spigotmc: Spigot"
|
||||
=== "Softdepend"
|
||||
```yaml title="plugin.yml"
|
||||
name: "MyPlugin"
|
||||
author: "author"
|
||||
version: "1.0.0"
|
||||
|
||||
main: "com.example.plugin.ExamplePlugin"
|
||||
|
||||
softdepend:
|
||||
- AdvancedServerList
|
||||
```
|
||||
=== "Depend"
|
||||
```yaml title="plugin.yml"
|
||||
name: "MyPlugin"
|
||||
author: "author"
|
||||
version: "1.0.0"
|
||||
|
||||
main: "com.example.plugin.ExamplePlugin"
|
||||
|
||||
depend:
|
||||
- AdvancedServerList
|
||||
```
|
||||
=== ":fontawesome-solid-paper-plane: Paper"
|
||||
=== "Softdepend"
|
||||
```yaml title="paper-plugin.yml"
|
||||
name: "MyPlugin"
|
||||
author: "author"
|
||||
version: "1.0.0"
|
||||
|
||||
main: "com.example.plugin.ExamplePlugin"
|
||||
|
||||
dependencies:
|
||||
server:
|
||||
AdvancedServerList:
|
||||
load: BEFORE
|
||||
required: false # Default, not required
|
||||
```
|
||||
=== "Depend"
|
||||
```yaml title="paper-plugin.yml"
|
||||
name: "MyPlugin"
|
||||
author: "author"
|
||||
version: "1.0.0"
|
||||
|
||||
main: "com.example.plugin.ExamplePlugin"
|
||||
|
||||
dependencies:
|
||||
server:
|
||||
AdvancedServerList:
|
||||
load: BEFORE
|
||||
required: true
|
||||
```
|
||||
=== ":octicons-git-merge-24: BungeeCord"
|
||||
=== "Softdepend"
|
||||
```yaml title="bungee.yml"
|
||||
name: "MyPlugin"
|
||||
author: "author"
|
||||
version: "1.0.0"
|
||||
|
||||
main: "com.example.plugin.ExamplePlugin"
|
||||
|
||||
softDepends:
|
||||
- AdvancedServerList
|
||||
```
|
||||
=== "Depend"
|
||||
```yaml title="bungee.yml"
|
||||
name: "MyPlugin"
|
||||
author: "author"
|
||||
version: "1.0.0"
|
||||
|
||||
main: "com.example.plugin.ExamplePlugin"
|
||||
|
||||
depends:
|
||||
- AdvancedServerList
|
||||
```
|
||||
=== ":octicons-git-merge-24: Velocity"
|
||||
=== "Softdepend (File)"
|
||||
```json title="velocity-plugin.json"
|
||||
{
|
||||
"id": "myplugin",
|
||||
"name": "MyPlugin",
|
||||
"version": "1.0.0",
|
||||
"authors": [
|
||||
"author"
|
||||
],
|
||||
"main": "com.example.plugin.ExamplePlugin",
|
||||
"dependencies": [
|
||||
{
|
||||
"id": "advancedserverlist",
|
||||
"optional": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
=== "Depend (File)"
|
||||
```json title="velocity-plugin.json"
|
||||
{
|
||||
"id": "myplugin",
|
||||
"name": "MyPlugin",
|
||||
"version": "1.0.0",
|
||||
"authors": [
|
||||
"author"
|
||||
],
|
||||
"main": "com.example.plugin.ExamplePlugin",
|
||||
"dependencies": [
|
||||
{
|
||||
"id": "advancedserverlist",
|
||||
"optional": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
=== "Softdepend (Annotation)"
|
||||
```java title="MyPlugin.java"
|
||||
@Plugin(
|
||||
id = "myplugin",
|
||||
name = "MyPlugin",
|
||||
version = "1.0.0",
|
||||
authors = {"author"},
|
||||
dependencies = {
|
||||
@Dependency(
|
||||
id = "advancedserverlist",
|
||||
optional = true
|
||||
)
|
||||
}
|
||||
)
|
||||
public class MyPlugin {
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
```
|
||||
=== "Depend (Annotation)"
|
||||
```java title="MyPlugin.java"
|
||||
@Plugin(
|
||||
id = "myplugin",
|
||||
name = "MyPlugin",
|
||||
version = "1.0.0",
|
||||
authors = {"author"},
|
||||
dependencies = {
|
||||
@Dependency(
|
||||
id = "advancedserverlist",
|
||||
optional = false // Default, not required
|
||||
)
|
||||
}
|
||||
)
|
||||
public class MyPlugin {
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
```
|
||||
/// tab | :simple-spigotmc: Spigot
|
||||
//// tab | Softdepend
|
||||
```yaml title="plugin.yml"
|
||||
name: "MyPlugin"
|
||||
author: "author"
|
||||
version: "1.0.0"
|
||||
|
||||
main: "com.example.plugin.ExamplePlugin"
|
||||
|
||||
softdepend:
|
||||
- AdvancedServerList
|
||||
```
|
||||
////
|
||||
|
||||
//// tab | Depend
|
||||
```yaml title="plugin.yml"
|
||||
name: "MyPlugin"
|
||||
author: "author"
|
||||
version: "1.0.0"
|
||||
|
||||
main: "com.example.plugin.ExamplePlugin"
|
||||
|
||||
depend:
|
||||
- AdvancedServerList
|
||||
```
|
||||
////
|
||||
///
|
||||
|
||||
/// tab | :fontawesome-solid-paper-plane: Paper
|
||||
//// tab | Softdepend
|
||||
```yaml title="paper-plugin.yml"
|
||||
name: "MyPlugin"
|
||||
author: "author"
|
||||
version: "1.0.0"
|
||||
|
||||
main: "com.example.plugin.ExamplePlugin"
|
||||
|
||||
dependencies:
|
||||
server:
|
||||
AdvancedServerList:
|
||||
load: BEFORE
|
||||
required: false # Default, not required
|
||||
```
|
||||
////
|
||||
|
||||
//// tab | Depend
|
||||
```yaml title="paper-plugin.yml"
|
||||
name: "MyPlugin"
|
||||
author: "author"
|
||||
version: "1.0.0"
|
||||
|
||||
main: "com.example.plugin.ExamplePlugin"
|
||||
|
||||
dependencies:
|
||||
server:
|
||||
AdvancedServerList:
|
||||
load: BEFORE
|
||||
required: true
|
||||
```
|
||||
////
|
||||
///
|
||||
|
||||
/// tab | :octicons-git-merge-24: BungeeCord
|
||||
//// tab | Softdepend
|
||||
```yaml title="bungee.yml"
|
||||
name: "MyPlugin"
|
||||
author: "author"
|
||||
version: "1.0.0"
|
||||
|
||||
main: "com.example.plugin.ExamplePlugin"
|
||||
|
||||
softDepends:
|
||||
- AdvancedServerList
|
||||
```
|
||||
////
|
||||
|
||||
//// tab | Depend
|
||||
```yaml title="bungee.yml"
|
||||
name: "MyPlugin"
|
||||
author: "author"
|
||||
version: "1.0.0"
|
||||
|
||||
main: "com.example.plugin.ExamplePlugin"
|
||||
|
||||
depends:
|
||||
- AdvancedServerList
|
||||
```
|
||||
////
|
||||
///
|
||||
|
||||
/// tab | :octicons-git-merge-24: Velocity
|
||||
//// tab | Softdepend (File)
|
||||
```json title="velocity-plugin.json"
|
||||
{
|
||||
"id": "myplugin",
|
||||
"name": "MyPlugin",
|
||||
"version": "1.0.0",
|
||||
"authors": [
|
||||
"author"
|
||||
],
|
||||
"main": "com.example.plugin.ExamplePlugin",
|
||||
"dependencies": [
|
||||
{
|
||||
"id": "advancedserverlist",
|
||||
"optional": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
////
|
||||
|
||||
//// tab | Depend (File)
|
||||
```json title="velocity-plugin.json"
|
||||
{
|
||||
"id": "myplugin",
|
||||
"name": "MyPlugin",
|
||||
"version": "1.0.0",
|
||||
"authors": [
|
||||
"author"
|
||||
],
|
||||
"main": "com.example.plugin.ExamplePlugin",
|
||||
"dependencies": [
|
||||
{
|
||||
"id": "advancedserverlist",
|
||||
"optional": false // Default, not required
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
////
|
||||
|
||||
//// tab | Softdepend (Annotation)
|
||||
```java title="MyPlugin.java"
|
||||
@Plugin(
|
||||
id = "myplugin",
|
||||
name = "MyPlugin",
|
||||
version = "1.0.0",
|
||||
authors = {"author"},
|
||||
dependencies = {
|
||||
@Dependency(
|
||||
id = "advancedserverlist",
|
||||
optional = true
|
||||
)
|
||||
}
|
||||
)
|
||||
public class MyPlugin {
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
```
|
||||
////
|
||||
|
||||
//// tab | Depend (Annotation)
|
||||
```java title="MyPlugin.java"
|
||||
@Plugin(
|
||||
id = "myplugin",
|
||||
name = "MyPlugin",
|
||||
version = "1.0.0",
|
||||
authors = {"author"},
|
||||
dependencies = {
|
||||
@Dependency(
|
||||
id = "advancedserverlist",
|
||||
optional = false // Default, not required
|
||||
)
|
||||
}
|
||||
)
|
||||
public class MyPlugin {
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
```
|
||||
////
|
||||
///
|
||||
|
||||
### 4. You're done!
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
template: redirect.html
|
||||
|
||||
location: https://github.com/Andre601/asl-api
|
||||
|
||||
title: Source Code
|
||||
icon: octicons/mark-github-16
|
||||
---
|
||||
|
||||
<!-- Comment to trigger proper build -->
|
||||
@@ -28,13 +28,22 @@ document$.subscribe(async () => {
|
||||
|
||||
function loadApiInfo(data) {
|
||||
const version = data["version"];
|
||||
const versionToken = '{version}';
|
||||
const versionToken = '{apiVersion}';
|
||||
const codeBlocks = document.querySelectorAll('.md-content pre code');
|
||||
for(const codeBlock of codeBlocks) {
|
||||
codeBlock.innerHTML = codeBlock.innerHTML.replace(new RegExp(versionToken, 'g'), version);
|
||||
}
|
||||
}
|
||||
|
||||
function loadPluginVersion(data) {
|
||||
const version = data["version"];
|
||||
const versionToken = '{version}'
|
||||
const entries = document.querySelectorAll('.md-content code');
|
||||
for(const entry of entries) {
|
||||
entry.innerHTML = entry.innerHTML.replace(new RegExp(versionToken, 'g'), version);
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchApiInfo() {
|
||||
const tag = await fetch("https://api.github.com/repos/Andre601/asl-api/releases/latest").then(_ => _.json());
|
||||
|
||||
@@ -60,12 +69,14 @@ document$.subscribe(async () => {
|
||||
|
||||
__md_set("__git_repo", data, sessionStorage);
|
||||
loadCodebergInfo(data);
|
||||
loadPluginVersion(data);
|
||||
}
|
||||
|
||||
if(!document.querySelector('[data-md-component="source"] .md-source__facts')) {
|
||||
const cached = __md_get("__git_repo", sessionStorage);
|
||||
if((cached != null) && (cached["version"])) {
|
||||
loadCodebergInfo(cached);
|
||||
loadPluginVersion(cached);
|
||||
} else {
|
||||
fetchInfo();
|
||||
}
|
||||
|
||||
@@ -23,11 +23,13 @@
|
||||
--md-badge-bg--example: #7c4dff1a;
|
||||
--md-badge-fg--quote: #9e9e9e;
|
||||
--md-badge-bg--quote: #9e9e9e1a;
|
||||
--md-badge-fg--deprecated: #ff5252;
|
||||
--md-badge-bg--deprecated: #ff52521a;
|
||||
|
||||
--badge-icon--note: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M17.263 2.177a1.75 1.75 0 0 1 2.474 0l2.586 2.586a1.75 1.75 0 0 1 0 2.474L19.53 10.03l-.012.013L8.69 20.378a1.753 1.753 0 0 1-.699.409l-5.523 1.68a.748.748 0 0 1-.747-.188.748.748 0 0 1-.188-.747l1.673-5.5a1.75 1.75 0 0 1 .466-.756L14.476 4.963ZM4.708 16.361a.26.26 0 0 0-.067.108l-1.264 4.154 4.177-1.271a.253.253 0 0 0 .1-.059l10.273-9.806-2.94-2.939-10.279 9.813ZM19 8.44l2.263-2.262a.25.25 0 0 0 0-.354l-2.586-2.586a.25.25 0 0 0-.354 0L16.061 5.5Z"></path></svg>');
|
||||
--badge-icon--abstract: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M5.962 2.513a.75.75 0 0 1-.475.949l-.816.272a.25.25 0 0 0-.171.237V21.25c0 .138.112.25.25.25h14.5a.25.25 0 0 0 .25-.25V3.97a.25.25 0 0 0-.17-.236l-.817-.272a.75.75 0 0 1 .474-1.424l.816.273A1.751 1.751 0 0 1 21 3.97v17.28A1.75 1.75 0 0 1 19.25 23H4.75A1.75 1.75 0 0 1 3 21.25V3.97a1.75 1.75 0 0 1 1.197-1.66l.816-.272a.75.75 0 0 1 .949.475Z"></path><path d="M7 1.75C7 .784 7.784 0 8.75 0h6.5C16.216 0 17 .784 17 1.75v1.5A1.75 1.75 0 0 1 15.25 5h-6.5A1.75 1.75 0 0 1 7 3.25Zm1.75-.25a.25.25 0 0 0-.25.25v1.5c0 .138.112.25.25.25h6.5a.25.25 0 0 0 .25-.25v-1.5a.25.25 0 0 0-.25-.25Z"></path></svg>');
|
||||
--badge-icon--info: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M13 7.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm-3 3.75a.75.75 0 0 1 .75-.75h1.5a.75.75 0 0 1 .75.75v4.25h.75a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1 0-1.5h.75V12h-.75a.75.75 0 0 1-.75-.75Z"></path><path d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Z"></path></svg>');
|
||||
--badge-icon--tip: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M14.265 1.627c0 3.545 1.869 5.327 3.479 7.021 1.54 1.62 3.006 3.163 3.006 6.102 0 4.812-3.753 8.25-8.565 8.25-4.813 0-8.935-3.421-8.935-8.25 0-2.039.962-4.011 2.509-4.899.305-.175.672.007.803.334C7.563 12.684 8.797 12.64 9.437 12c.388-.387.47-1.116-.004-2.062-2.405-4.812 1.863-8.279 4.2-8.854.336-.082.615.198.632.543ZM12.185 21.5c4.059 0 7.065-2.84 7.065-6.75 0-2.337-1.093-3.489-2.678-5.158l-.021-.023c-1.44-1.517-3.139-3.351-3.649-6.557a6.148 6.148 0 0 0-1.911 1.76c-.787 1.144-1.147 2.633-.216 4.495.603 1.205.777 2.74-.277 3.794-.657.657-1.762 1.1-2.956.586-.752-.324-1.353-.955-1.838-1.79-.567.706-.954 1.74-.954 2.893 0 3.847 3.288 6.75 7.435 6.75Z"></path></svg>');
|
||||
--badge-icon--tip: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M12 2.5c-3.81 0-6.5 2.743-6.5 6.119 0 1.536.632 2.572 1.425 3.56.172.215.347.422.527.635l.096.112c.21.25.427.508.63.774.404.531.783 1.128.995 1.834a.75.75 0 0 1-1.436.432c-.138-.46-.397-.89-.753-1.357a18.111 18.111 0 0 0-.582-.714l-.092-.11c-.18-.212-.37-.436-.555-.667C4.87 12.016 4 10.651 4 8.618 4 4.363 7.415 1 12 1s8 3.362 8 7.619c0 2.032-.87 3.397-1.755 4.5-.185.23-.375.454-.555.667l-.092.109c-.21.248-.405.481-.582.714-.356.467-.615.898-.753 1.357a.751.751 0 0 1-1.437-.432c.213-.706.592-1.303.997-1.834.202-.266.419-.524.63-.774l.095-.112c.18-.213.355-.42.527-.634.793-.99 1.425-2.025 1.425-3.561C18.5 5.243 15.81 2.5 12 2.5ZM8.75 18h6.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5Zm.75 3.75a.75.75 0 0 1 .75-.75h3.5a.75.75 0 0 1 0 1.5h-3.5a.75.75 0 0 1-.75-.75Z"></path></svg>');
|
||||
--badge-icon--success: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M21.03 5.72a.75.75 0 0 1 0 1.06l-11.5 11.5a.747.747 0 0 1-1.072-.012l-5.5-5.75a.75.75 0 1 1 1.084-1.036l4.97 5.195L19.97 5.72a.75.75 0 0 1 1.06 0Z"></path></svg>');
|
||||
--badge-icon--question: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M10.97 8.265a1.45 1.45 0 0 0-.487.57.75.75 0 0 1-1.341-.67c.2-.402.513-.826.997-1.148C10.627 6.69 11.244 6.5 12 6.5c.658 0 1.369.195 1.934.619a2.45 2.45 0 0 1 1.004 2.006c0 1.033-.513 1.72-1.027 2.215-.19.183-.399.358-.579.508l-.147.123a4.329 4.329 0 0 0-.435.409v1.37a.75.75 0 1 1-1.5 0v-1.473c0-.237.067-.504.247-.736.22-.28.486-.517.718-.714l.183-.153.001-.001c.172-.143.324-.27.47-.412.368-.355.569-.676.569-1.136a.953.953 0 0 0-.404-.806C12.766 8.118 12.384 8 12 8c-.494 0-.814.121-1.03.265ZM13 17a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path><path d="M12 1c6.075 0 11 4.925 11 11s-4.925 11-11 11S1 18.075 1 12 5.925 1 12 1ZM2.5 12a9.5 9.5 0 0 0 9.5 9.5 9.5 9.5 0 0 0 9.5-9.5A9.5 9.5 0 0 0 12 2.5 9.5 9.5 0 0 0 2.5 12Z"></path></svg>');
|
||||
--badge-icon--warning: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M13 17.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm-.25-8.25a.75.75 0 0 0-1.5 0v4.5a.75.75 0 0 0 1.5 0v-4.5Z"></path><path d="M9.836 3.244c.963-1.665 3.365-1.665 4.328 0l8.967 15.504c.963 1.667-.24 3.752-2.165 3.752H3.034c-1.926 0-3.128-2.085-2.165-3.752Zm3.03.751a1.002 1.002 0 0 0-1.732 0L2.168 19.499A1.002 1.002 0 0 0 3.034 21h17.932a1.002 1.002 0 0 0 .866-1.5L12.866 3.994Z"></path></svg>');
|
||||
@@ -36,22 +38,31 @@
|
||||
--badge-icon--bug: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M7.72.22a.75.75 0 0 1 1.06 0l1.204 1.203A4.98 4.98 0 0 1 12 1c.717 0 1.4.151 2.016.423L15.22.22a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-.971.972A4.991 4.991 0 0 1 17 6v1.104a2.755 2.755 0 0 1 1.917 1.974l1.998-.999a.75.75 0 0 1 .67 1.342L19 10.714V13.5l3.25.003a.75.75 0 0 1 0 1.5L19 15.001V16c0 .568-.068 1.134-.204 1.686l.04.018 2.75 1.375a.75.75 0 1 1-.671 1.342l-2.638-1.319A6.998 6.998 0 0 1 12 23a6.998 6.998 0 0 1-6.197-3.742l-2.758 1.181a.752.752 0 0 1-1.064-.776.752.752 0 0 1 .474-.602l2.795-1.199A6.976 6.976 0 0 1 5 16v-.996H1.75a.75.75 0 0 1 0-1.5H5v-2.79L2.415 9.42a.75.75 0 0 1 .67-1.342l1.998.999A2.756 2.756 0 0 1 7 7.104V6a4.99 4.99 0 0 1 1.69-3.748l-.97-.972a.75.75 0 0 1 0-1.06ZM6.5 9.75V16a5.5 5.5 0 1 0 11 0V9.75c0-.69-.56-1.25-1.25-1.25h-8.5c-.69 0-1.25.56-1.25 1.25ZM8.5 7h7V6a3.5 3.5 0 1 0-7 0Z"></path></svg>');
|
||||
--badge-icon--example: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M8 8.807V3.5h-.563a.75.75 0 0 1 0-1.5h9.125a.75.75 0 0 1 0 1.5H16v5.307l5.125 9.301c.964 1.75-.302 3.892-2.299 3.892H5.174c-1.998 0-3.263-2.142-2.3-3.892ZM4.189 18.832a1.123 1.123 0 0 0 .985 1.668h13.652a1.123 1.123 0 0 0 .985-1.668L17.7 15H6.3ZM14.5 3.5h-5V9a.75.75 0 0 1-.093.362L7.127 13.5h9.746l-2.28-4.138A.75.75 0 0 1 14.5 9Z"></path></svg>');
|
||||
--badge-icon--quote: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M3 6.25a.75.75 0 0 1 .75-.75h13.5a.75.75 0 0 1 0 1.5H3.75A.75.75 0 0 1 3 6.25Zm5 6.063a.75.75 0 0 1 .75-.75h11.5a.75.75 0 0 1 0 1.5H8.75a.75.75 0 0 1-.75-.75Zm0 5.937a.75.75 0 0 1 .75-.75h11.5a.75.75 0 0 1 0 1.5H8.75a.75.75 0 0 1-.75-.75ZM3.75 11a.75.75 0 0 1 .75.75v7a.75.75 0 0 1-1.5 0v-7a.75.75 0 0 1 .75-.75Z"></path></svg>');
|
||||
--badge-icon--deprecated: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M16 1.75V3h5.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H8V1.75C8 .784 8.784 0 9.75 0h4.5C15.216 0 16 .784 16 1.75Zm-6.5 0V3h5V1.75a.25.25 0 0 0-.25-.25h-4.5a.25.25 0 0 0-.25.25ZM4.997 6.178a.75.75 0 1 0-1.493.144L4.916 20.92a1.75 1.75 0 0 0 1.742 1.58h10.684a1.75 1.75 0 0 0 1.742-1.581l1.413-14.597a.75.75 0 0 0-1.494-.144l-1.412 14.596a.25.25 0 0 1-.249.226H6.658a.25.25 0 0 1-.249-.226L4.997 6.178Z"></path><path d="M9.206 7.501a.75.75 0 0 1 .793.705l.5 8.5A.75.75 0 1 1 9 16.794l-.5-8.5a.75.75 0 0 1 .705-.793Zm6.293.793A.75.75 0 1 0 14 8.206l-.5 8.5a.75.75 0 0 0 1.498.088l.5-8.5Z"></path></svg>');
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge {
|
||||
font-size: .85em;
|
||||
/*
|
||||
* Grid stuff
|
||||
*/
|
||||
.mdx-grid-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: .5fr 9fr;
|
||||
gap: 1rem;
|
||||
|
||||
border: .075rem solid var(--md-badge-fg--note);
|
||||
border-radius: .1rem;
|
||||
padding: .3rem;
|
||||
border-radius: .2rem;
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon {
|
||||
background: var(--md-accent-fg-color--transparent);
|
||||
padding: .5rem .3rem;
|
||||
margin-left: -.3rem;
|
||||
.mdx-grid-child {
|
||||
align-self: center;
|
||||
font-size: .64rem;
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon::before {
|
||||
.mdx-grid-child.mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--note);
|
||||
}
|
||||
|
||||
.mdx-grid-child.mdx-grid-child--icon::before {
|
||||
content: "";
|
||||
|
||||
background-color: var(--md-badge-fg--note);
|
||||
@@ -60,198 +71,209 @@
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: contain;
|
||||
|
||||
display: inline-block;
|
||||
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
|
||||
vertical-align: middle;
|
||||
margin: .4rem;
|
||||
|
||||
display: block;
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--note);
|
||||
mask-image: var(--badge-icon--note);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge__text {
|
||||
padding: .3rem .3rem;
|
||||
margin: .3rem;
|
||||
}
|
||||
|
||||
/*
|
||||
* Types
|
||||
*/
|
||||
|
||||
/* Abstract */
|
||||
.md-typeset .mdx-badge.mdx-badge--abstract {
|
||||
.mdx-admo--abstract {
|
||||
border-color: var(--md-badge-fg--abstract);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--abstract {
|
||||
.mdx-admo--abstract .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--abstract);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--abstract::before {
|
||||
.mdx-admo--abstract .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--abstract);
|
||||
|
||||
mask-image: var(--badge-icon--abstract);
|
||||
-webkit-mask-image: var(--badge-icon--abstract);
|
||||
mask-image: var(--badge-icon--abstract);
|
||||
}
|
||||
|
||||
/* Info */
|
||||
.md-typeset .mdx-badge.mdx-badge--info {
|
||||
.mdx-admo--info {
|
||||
border-color: var(--md-badge-fg--info);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--info {
|
||||
.mdx-admo--info .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--info);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--info::before {
|
||||
.mdx-admo--info .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--info);
|
||||
|
||||
mask-image: var(--badge-icon--info);
|
||||
-webkit-mask-image: var(--badge-icon--info);
|
||||
mask-image: var(--badge-icon--info);
|
||||
}
|
||||
|
||||
/* Tip */
|
||||
.md-typeset .mdx-badge.mdx-badge--tip {
|
||||
.mdx-admo--tip {
|
||||
border-color: var(--md-badge-fg--tip);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--tip {
|
||||
.mdx-admo--tip .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--tip);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--tip::before {
|
||||
.mdx-admo--tip .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--tip);
|
||||
|
||||
mask-image: var(--badge-icon--tip);
|
||||
-webkit-mask-image: var(--badge-icon--tip);
|
||||
mask-image: var(--badge-icon--tip);
|
||||
}
|
||||
|
||||
/* Success */
|
||||
.md-typeset .mdx-badge.mdx-badge--success {
|
||||
.mdx-admo--success {
|
||||
border-color: var(--md-badge-fg--success);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--success {
|
||||
.mdx-admo--success .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--success);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--success::before {
|
||||
.mdx-admo--success .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--success);
|
||||
|
||||
mask-image: var(--badge-icon--success);
|
||||
-webkit-mask-image: var(--badge-icon--success);
|
||||
mask-image: var(--badge-icon--success);
|
||||
}
|
||||
|
||||
/* Question */
|
||||
.md-typeset .mdx-badge.mdx-badge--question {
|
||||
.mdx-admo--question {
|
||||
border-color: var(--md-badge-fg--question);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--question {
|
||||
.mdx-admo--question .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--question);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--question::before {
|
||||
.mdx-admo--question .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--question);
|
||||
|
||||
mask-image: var(--badge-icon--question);
|
||||
-webkit-mask-image: var(--badge-icon--question);
|
||||
mask-image: var(--badge-icon--question);
|
||||
}
|
||||
|
||||
/* Warning */
|
||||
.md-typeset .mdx-badge.mdx-badge--warning {
|
||||
.mdx-admo--warning {
|
||||
border-color: var(--md-badge-fg--warning);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--warning {
|
||||
.mdx-admo--warning .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--warning);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--warning::before {
|
||||
.mdx-admo--warning .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--warning);
|
||||
|
||||
mask-image: var(--badge-icon--warning);
|
||||
-webkit-mask-image: var(--badge-icon--warning);
|
||||
mask-image: var(--badge-icon--warning);
|
||||
}
|
||||
|
||||
/* Failure */
|
||||
.md-typeset .mdx-badge.mdx-badge--failure {
|
||||
.mdx-admo--failure {
|
||||
border-color: var(--md-badge-fg--failure);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--failure {
|
||||
.mdx-admo--failure .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--failure);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--failure::before {
|
||||
.mdx-admo--failure .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--failure);
|
||||
|
||||
mask-image: var(--badge-icon--failure);
|
||||
-webkit-mask-image: var(--badge-icon--failure);
|
||||
mask-image: var(--badge-icon--failure);
|
||||
}
|
||||
|
||||
/* Danger */
|
||||
.md-typeset .mdx-badge.mdx-badge--danger {
|
||||
.mdx-admo--danger {
|
||||
border-color: var(--md-badge-fg--danger);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--danger {
|
||||
.mdx-admo--danger .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--danger);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--danger::before {
|
||||
.mdx-admo--danger .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--danger);
|
||||
|
||||
mask-image: var(--badge-icon--danger);
|
||||
-webkit-mask-image: var(--badge-icon--danger);
|
||||
mask-image: var(--badge-icon--danger);
|
||||
}
|
||||
|
||||
/* Bug */
|
||||
.md-typeset .mdx-badge.mdx-badge--bug {
|
||||
.mdx-admo--bug {
|
||||
border-color: var(--md-badge-fg--bug);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--bug {
|
||||
.mdx-admo--bug .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--bug);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--bug::before {
|
||||
.mdx-admo--bug .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--bug);
|
||||
|
||||
mask-image: var(--badge-icon--bug);
|
||||
-webkit-mask-image: var(--badge-icon--bug);
|
||||
mask-image: var(--badge-icon--bug);
|
||||
}
|
||||
|
||||
/* Example */
|
||||
.md-typeset .mdx-badge.mdx-badge--example {
|
||||
.mdx-admo--example {
|
||||
border-color: var(--md-badge-fg--example);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--example {
|
||||
.mdx-admo--example .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--example);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--example::before {
|
||||
.mdx-admo--example .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--example);
|
||||
|
||||
mask-image: var(--badge-icon--example);
|
||||
-webkit-mask-image: var(--badge-icon--example);
|
||||
mask-image: var(--badge-icon--example);
|
||||
}
|
||||
|
||||
/* Quote */
|
||||
.md-typeset .mdx-badge.mdx-badge--quote {
|
||||
.mdx-admo--quote {
|
||||
border-color: var(--md-badge-fg--quote);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--quote {
|
||||
.mdx-admo--quote .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--quote);
|
||||
}
|
||||
|
||||
.md-typeset .mdx-badge .mdx-badge__icon.mdx-badge--quote::before {
|
||||
.mdx-admo--quote .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--quote);
|
||||
|
||||
mask-image: var(--badge-icon--quote);
|
||||
-webkit-mask-image: var(--badge-icon--quote);
|
||||
mask-image: var(--badge-icon--quote);
|
||||
}
|
||||
|
||||
/* Deprecated */
|
||||
.mdx-admo--deprecated {
|
||||
border-color: var(--md-badge-fg--deprecated);
|
||||
}
|
||||
|
||||
.mdx-admo--deprecated .mdx-grid-child--icon {
|
||||
background-color: var(--md-badge-bg--deprecated);
|
||||
}
|
||||
|
||||
.mdx-admo--deprecated .mdx-grid-child--icon::before {
|
||||
background-color: var(--md-badge-fg--deprecated);
|
||||
|
||||
-webkit-mask-image: var(--badge-icon--deprecated);
|
||||
mask-image: var(--badge-icon--deprecated);
|
||||
}
|
||||
+7
-12
@@ -6,7 +6,7 @@ icon: octicons/list-unordered-24
|
||||
|
||||
## About
|
||||
|
||||
<!-- admo:info The below examples may only work in v1.10.0 or newer! -->
|
||||
<!-- admo:info The below examples may only work in v3.7.0 or newer! -->
|
||||
|
||||
This page lists some examples you may want to use for your proxy or server.
|
||||
|
||||
@@ -38,8 +38,7 @@ This example here shows a separate MOTD and player count message for when the pl
|
||||
priority: 1
|
||||
|
||||
# Display this profile, if the version of the player is below 760 (1.19.1)
|
||||
conditions:
|
||||
- '${player protocol} < 760'
|
||||
condition: '${player protocol} < 760'
|
||||
|
||||
motd:
|
||||
- '<red>You are using an outdated client!'
|
||||
@@ -57,8 +56,7 @@ This profile would display a MOTD without HEX colours if the player's version is
|
||||
priority: 1
|
||||
|
||||
# Display this profile, if the version of the player is below 735 (1.16)
|
||||
conditions:
|
||||
- '${player protocol} < 735'
|
||||
condition: '${player protocol} < 735'
|
||||
|
||||
motd:
|
||||
- '<grey>Welcome to <aqua>YourServer.com</aqua>!'
|
||||
@@ -79,8 +77,7 @@ Displays a separate profile for when the player has been banned from the server.
|
||||
```yaml title="banned.yml"
|
||||
priority: 1
|
||||
|
||||
conditions:
|
||||
- '${player isBanned} = true'
|
||||
condition: '${player isBanned}'
|
||||
|
||||
motd:
|
||||
- '<red>You have been <bold>BANNED</bold>!'
|
||||
@@ -103,8 +100,7 @@ Display a different profile when the playing pings a specific domain/IP.
|
||||
```yaml title="specific-host.yml"
|
||||
priority: 1
|
||||
|
||||
conditions:
|
||||
- '${server host} = other.example.com'
|
||||
condition: '${server host} = "host.example.com"'
|
||||
|
||||
motd:
|
||||
- '<grey>Please use <aqua>mc.example.com'
|
||||
@@ -118,12 +114,11 @@ Display a different profile, if the player pinging the server is "known" by Adva
|
||||
```yaml title="personalized.yml"
|
||||
priority: 1
|
||||
|
||||
conditions:
|
||||
- `${player name} != Anonymous` # "Anonymous" should be replaced with whatever you use in 'unknown_player'
|
||||
condition: '${player name} != Anonymous' # "Anonymous" would be the value from the "unknownPlayer > name" option.
|
||||
|
||||
motd:
|
||||
- '<grey>Hello there <aqua>${player name}</aqua>!'
|
||||
- '<grey>It's nice to see you again.'
|
||||
- '<grey>It''s nice to see you again.'
|
||||
|
||||
playerCount:
|
||||
hover:
|
||||
|
||||
@@ -0,0 +1,380 @@
|
||||
---
|
||||
icon: octicons/milestone-24
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
|
||||
This page will explain how to set up AdvancedServerList and make it work for your server.
|
||||
It tries to be an easy to understand as possible. But if you still have problems, consider joining the [Discord Server](https://discord.gg/6dazXp6) for help.
|
||||
|
||||
## 1. Download the plugin { #download-the-plugin }
|
||||
|
||||
The first step would be to download the plugin from a download page of your choice. As of writing this is AdvancedServerList updated and available on these sites:
|
||||
|
||||
- [Modrinth]
|
||||
- [Codeberg]
|
||||
|
||||
[modrinth]: https://modrinth.com/plugin/advancedserverlist
|
||||
[codeberg]: https://codeberg.org/Andre601/AdvancedServerList
|
||||
|
||||
The plugin is also available on these platforms, but not actively updated there anymore:
|
||||
|
||||
- [Spigot] (Latest version: `3.3.0-b1`)
|
||||
- [Hangar] (Latest version: `3.5.0`)
|
||||
|
||||
[spigot]: https://www.spigotmc.org/resources/102910/
|
||||
[hangar]: https://hangar.papermc.io/Andre_601/AdvancedServerList
|
||||
|
||||
The plugin is available for Paper, BungeeCord, Waterfall and Velocity, and has been tested on these platforms. It may support additional forks, but this is not guaranteed.
|
||||
|
||||
The plugin also supports these additional plugins. They are all optional.
|
||||
|
||||
- [PlaceholderAPI] - Used on the Spigot and Paper server for additional Placeholder parsing.
|
||||
- [ViaVersion] - Used on the Paper server for additional protocol version handling.
|
||||
- [PAPIProxyBridge] - Used on BungeeCord, Waterfall and Velocity for PlaceholderAPI support.
|
||||
- [Maintenance] - Used to disable server list handling while maintenance is active.
|
||||
|
||||
[placeholderapi]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
|
||||
[viaversion]: https://hangar.papermc.io/ViaVersion/ViaVersion
|
||||
[papiproxybridge]: https://hangar.papermc.io/William278/PAPIProxyBridge
|
||||
[maintenance]: https://hangar.papermc.io/kennytv/Maintenance
|
||||
|
||||
## 2. Installation { #installation }
|
||||
|
||||
Installing the plugin is as simple as moving the jar file into the plugins folder. Just make sure to download the right version of AdvancedServerList for the right platform.
|
||||
Here is a quick table showing the jar file name with the platforms it is made for:
|
||||
|
||||
| Jar file name | Platforms |
|
||||
|-----------------------------------------------|-----------------------|
|
||||
| `AdvancedServerList-Paper-{version}.jar` | Paper |
|
||||
| `AdvancedServerList-BungeeCord-{version}.jar` | BungeeCord, Waterfall |
|
||||
| `AdvancedServerList-Velocity-{version}.jar` | Velocity |
|
||||
|
||||
After you added it to your plugins folder - alongside any other dependency you may want - (re)start your server or proxy to enable the plugin.
|
||||
If everything goes well should AdvancedServerList create a folder named `AdvancedServerList` (`advancedserverlist` on Velocity) with additional files and folders inside of it.
|
||||
|
||||
### Folder structure
|
||||
|
||||
When you install AdvancedServerList for the first time should it have created the following file structure inside the plugins folder of your Server or Proxy:
|
||||
```
|
||||
AdvancedServerList/
|
||||
├── favicons/
|
||||
├── profiles/
|
||||
│ └── default.yml
|
||||
└── config.yml
|
||||
```
|
||||
Let's cover the files and folders...
|
||||
|
||||
#### Favicons folder
|
||||
|
||||
This folder allows you to store PNG images that should be used as favicons by the plugin. A favicon from this folder can be used by referencing the name (Including the `.png` file extension) in the [`favicon` option of the server list profile](../profiles/index.md#favicon).
|
||||
|
||||
#### Profiles folder and default.yml { #profiles-folder-and-default-yml }
|
||||
|
||||
The profiles folder is home of the server list profile files which allow you to modify the server list entry of your server in a player's multiplayer screen.
|
||||
On first creation will the folder have a `default.yml` file. This file contains all the options available to use alongside comments to try and help you in using it properly.
|
||||
|
||||
/// details | default.yml content
|
||||
```yaml
|
||||
#
|
||||
# Set the priority of this profile.
|
||||
# Higher number = Higher priority.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#priority
|
||||
#
|
||||
priority: 0
|
||||
|
||||
#
|
||||
# Set conditions that needs to be met.
|
||||
# Only when all conditions return true will the profile be shown (Given no profile with higher priority is used).
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#conditions
|
||||
#
|
||||
#conditions:
|
||||
# - '{playerVersion} < 759'
|
||||
|
||||
#
|
||||
# Option that allows you to define multiple profiles to use.
|
||||
# Each entry supports the same options as the server list profile does. Whenever an option is not present, or set to
|
||||
# an empty value (If supported) would the option in the file be used (if present).
|
||||
# This allows you to f.e. randomize the MOTD while keeping other options the same, without copy-pasting the same options.
|
||||
#
|
||||
# A profile will be selected randomly.
|
||||
#
|
||||
# Remove this option or set it to profiles: [] to use the global options of this file.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#profiles
|
||||
#
|
||||
#profiles:
|
||||
# - motd:
|
||||
# - '<aqua>Line 1'
|
||||
# - '<aqua>Line 2'
|
||||
# favicon: ''
|
||||
# playerCount:
|
||||
# hidePlayers: false
|
||||
# hover:
|
||||
# - '<green>Line 1'
|
||||
# - '<green>Line 2'
|
||||
# - '<green>Line 3'
|
||||
# text: ''
|
||||
# extraPlayers:
|
||||
# enabled: false
|
||||
# amount: 0
|
||||
|
||||
#
|
||||
# Set the default (Global) MOTD used by this server list profile.
|
||||
# Supports HEX colors for 1.16+ servers including gradients using MiniMessage's <gradient:color:color> format.
|
||||
#
|
||||
# Remove this option or set it to motd: [] to not alter the MOTD.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#motd
|
||||
#
|
||||
motd:
|
||||
- '<grey>Line 1'
|
||||
- '<grey>Line 2'
|
||||
|
||||
#
|
||||
# Allows you to set a global (Default) favicon for this server list profile.
|
||||
# You can use one of three possible options:
|
||||
# 1. A file name matching a PNG file located in the 'favicons' folder (Needs to end with .png)
|
||||
# 2. A URL pointing to a valid Image
|
||||
# 3. ${player name} to display the player's head as favicon. Uses https://mc-heads.net for this
|
||||
#
|
||||
# Remove this option or set to favicon: '' to not replace the Favicon.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#favicon
|
||||
#
|
||||
favicon: ''
|
||||
|
||||
#
|
||||
# Contains various options to manipulate the player count (Text displaying online and max players allowed).
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#playercount
|
||||
#
|
||||
playerCount:
|
||||
#
|
||||
# Whether AdvancedServerList should hide the player count or not.
|
||||
# When set to true will the player count display '???' instead of <online>/<max>
|
||||
#
|
||||
# Note that when this is enabled will all other options, except for 'extraPlayers', be ignored.
|
||||
#
|
||||
# Defaults to false when not present.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#hideplayers
|
||||
#
|
||||
hidePlayers: false
|
||||
#
|
||||
# Sets the text displayed when hovering over the player count.
|
||||
#
|
||||
# Remove this option or set it to hover: [] to not modify the player samples on the player count.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#hover
|
||||
#
|
||||
hover:
|
||||
- '<grey>Line 1'
|
||||
- '<grey>Line 2'
|
||||
- '<grey>Line 3'
|
||||
#
|
||||
# Modifies the text that usually displays '<online>/<max>'
|
||||
#
|
||||
# Note that when used, the Ping icon will display as 'outdated server'/'outdated client'.
|
||||
# This is nothing that can be fixed or avoided and would require changes from Mojang.
|
||||
#
|
||||
# Remove this option or set it to text: '' to not modify the player count text.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#text
|
||||
#
|
||||
text: ''
|
||||
#
|
||||
# Allows you to modify the max player count displayed.
|
||||
# Note that this will affect ${server playersMax} (Except for when used in conditions).
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#extraplayers
|
||||
#
|
||||
extraPlayers:
|
||||
#
|
||||
# Enables/Disables the extraPlayers option.
|
||||
# When enabled will the total amount of players allowed to join be modified to the current
|
||||
# number of online players + 'amount'
|
||||
#
|
||||
# Defaults to false when not present.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#extraplayers-enabled
|
||||
#
|
||||
enabled: false
|
||||
#
|
||||
# Sets how much should be added/subtracted from the current number of online players
|
||||
# to then use for the max player count.
|
||||
#
|
||||
# Example:
|
||||
# When set to 1 while 10 players are online would the player count - if unmodified -
|
||||
# display '10/11'. When -1 is used will it display '10/9'
|
||||
#
|
||||
# Defaults to 0 when not present.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#extraplayers-amount
|
||||
#
|
||||
amount: 0
|
||||
#
|
||||
# Allows you to set the max players that could join your server.
|
||||
# Note that this option influences the '${server playersMax}' placeholder.
|
||||
#
|
||||
# The settings of this option have no effect should 'extraPlayers' be enabled
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#maxplayers
|
||||
#
|
||||
maxPlayers:
|
||||
#
|
||||
# Enables/Disables the maxPlayers option.
|
||||
# When enabled will the total amount of players allowed to join be changed to what 'amount' is set to.
|
||||
#
|
||||
# Defaults to false when not present.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#maxplayers-enabled
|
||||
#
|
||||
enabled: false
|
||||
#
|
||||
# Sets the number to display for the max number of players allowed to join your server.
|
||||
#
|
||||
# Example:
|
||||
# Setting this option to 0 (Default) while 1 player is online would display '1/0'
|
||||
#
|
||||
# Defaults to 0 if not set.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#maxplayers-amount
|
||||
#
|
||||
amount: 0
|
||||
```
|
||||
///
|
||||
|
||||
#### Config.yml
|
||||
|
||||
The config.yml file contains settings related to the plugin itself and some of its functionality.
|
||||
These functions include, but aren't limited to:
|
||||
|
||||
- Setting the default name and UUID used for an unknown (Not cached) player.
|
||||
- Disabling/Enabling caching of players.
|
||||
- Disabling/Enabling checking for updates.
|
||||
- Disabling/Enabling debug mode.
|
||||
- The config version used for migration. Don't touch this, or it may reset your config.
|
||||
|
||||
Similar to the default.yml is this file containing comments to try and explain the settings in questions.
|
||||
Do note that if the config gets migrated from an older version, that the comments will be discarded in the process, unfortunately.
|
||||
|
||||
/// details | default config.yml content
|
||||
```yaml
|
||||
#
|
||||
# Used for when AdvancedServerList doesn't have a cached player to use for player placeholders.
|
||||
#
|
||||
unknownPlayer:
|
||||
#
|
||||
# The name to use. Defaults to Anonymous.
|
||||
#
|
||||
name: "Anonymous"
|
||||
#
|
||||
# The UUID to use. Defaults to 606e2ff0-ed77-4842-9d6c-e1d3321c7838 (UUID of MHF_Question).
|
||||
#
|
||||
uuid: "606e2ff0-ed77-4842-9d6c-e1d3321c7838"
|
||||
|
||||
#
|
||||
# Should the Caching of players be disabled?
|
||||
#
|
||||
# When set to true will AdvancedServerList not load any players from the cache.data file (if present) nor save any to it.
|
||||
# Placeholders that rely on the player being cached (such as ${player name}) will not work while this option is enabled.
|
||||
#
|
||||
# Defaults to false when not present.
|
||||
#
|
||||
disableCache: false
|
||||
|
||||
#
|
||||
# Should AdvancedServerList check for new versions?
|
||||
#
|
||||
# When set to true will AdvancedServerList check for a new version on modrinth.com every 12 hours and inform you in the
|
||||
# console about whether it found any new update or not.
|
||||
#
|
||||
# Defaults to false when not present.
|
||||
#
|
||||
checkUpdates: true
|
||||
|
||||
#
|
||||
# Should debug mode be enabled?
|
||||
#
|
||||
# When set to true will AdvancedServerList print additional messages to the console prefixed with "[DEBUG]".
|
||||
# It is recommended to only enable this when having problems or when being told to by the plugin dev, as it could
|
||||
# otherwise cause significant spam in your console.
|
||||
#
|
||||
# Defaults to false when not present.
|
||||
#
|
||||
debug: false
|
||||
|
||||
#
|
||||
# DO NOT EDIT!
|
||||
#
|
||||
# This is used internally to determine if the config needs to be migrated.
|
||||
# Changing or even removing this option could result in your config being broken.
|
||||
#
|
||||
config-version: 2
|
||||
```
|
||||
///
|
||||
|
||||
#### Additionally created files and folders
|
||||
|
||||
There are certain files and folders that get created when certain events happen:
|
||||
|
||||
- A `playercache.json` file will be created on plugin shutdown containing a list of IPs, UUIDs and Player names for every player that joined the server while AdvancedServerList was running.
|
||||
This file allows to replace `${player name}` and `${player uuid}` with their name or UUID respectively, while they are not on the server, by using the IP they used to join with.
|
||||
This file is not created nor updated when `disableCache` is set to `true` in the config.yml
|
||||
- A `backups` folder containing old config.yml files.
|
||||
This folder is created when AdvancedServerList migrates your old config to a new version. This allows you to transfer settings over in case the migration didn't work properly.
|
||||
|
||||
## 3. Creating your first profile { #creating-your-first-profile }
|
||||
|
||||
Creating your first profile is relatively simple.
|
||||
|
||||
To start, open the `default.yml` file located inside the `profiles` folder using a file editor of your choice (VSCode or Notepad++ are recommended). It should contain all the available options for a server list profile.
|
||||
Next can you edit the options available to whatever you like. All text options (Except [conditions](../profiles/index.md#conditions)) support [MiniMessage formatting](../profiles/formatting.md).
|
||||
|
||||
If you're unsure how a specific option should look like, head over to the [Profiles page](../profiles/index.md) for more information about the general structure.
|
||||
All you need to know is, that a bare-bones server list profile requires a valid [priority](../profiles/index.md#priority) and at least one of the settings to be present.
|
||||
|
||||
To give an example is here a basic profile that only modifies the MOTD and nothing else:
|
||||
```yaml title="default.yml"
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- 'Hello'
|
||||
- 'World!'
|
||||
```
|
||||
|
||||
### Additional profiles
|
||||
|
||||
To add additional profiles, create a new YAML file inside the `profiles` folder. The name doesn't matter, but it is recommended to keep it lowercase, use alphanumeric characters (`a-z, 0-9`), hyphens (`-`), underscores (`_`) and avoid spaces.
|
||||
|
||||
Inside the file, add a priority and at least one setting, similar to the above shown example.
|
||||
This would already be enough and AdvancedServerList would use it. If you however want to only show it when certain conditions are met, should you set the priority to a higher value and add conditions.
|
||||
|
||||
Conditions can be multiple strings containing [operands](../profiles/index.md#operands) to evaluate them. As an example `${server playersOnline} >= 10` would return true if the current number of online players is larger or equal to 10.
|
||||
|
||||
Here is another example profile using conditions:
|
||||
```yaml title="other_profile.yml"
|
||||
priority: 1
|
||||
|
||||
conditions:
|
||||
- '${player isBanned} = true'
|
||||
|
||||
motd:
|
||||
- '<red>You got <bold>banned</bold> from this server.'
|
||||
```
|
||||
|
||||
### Further examples
|
||||
|
||||
The [Examples page](../examples/index.md) contains more examples of different server list profiles for all kinds of situations.
|
||||
|
||||
## 4. Loading profiles { #loading-profiles }
|
||||
|
||||
Once you've set up your server list profile(s) is it time to load it/them.
|
||||
To do this, simply run `/asl reload` as player (Requires permission `advancedserverlist.admin` or `advancedserverlist.command.reload`) or through the Server/Proxy console.
|
||||
|
||||
The plugin should then load any valid YAML file inside the `profiles` folder to then use.
|
||||
|
||||
And that's already it! You now have a working server list profile for your server.
|
||||
+19
-15
@@ -24,13 +24,11 @@ If you're new to the plugin is it recommended to check out the [Profiles page](p
|
||||
|
||||
AdvancedServerList supports the following platforms:
|
||||
|
||||
[![spigot-img]{ width="64" loading="lazy" }][spigot]
|
||||
[![paper-img]{ width="64" loading="lazy" }][paper]
|
||||
[![bungeecord-img]{ width="64" loading="lazy" }][spigot]
|
||||
[![waterfall-img]{ width="64" loading="lazy" }][paper]
|
||||
[![velocity-img]{ width="64" loading="lazy" }][velocity]
|
||||
|
||||
[spigot-img]: https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/spigot_vector.svg "Tested on Spigot"
|
||||
[paper-img]: https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/paper_vector.svg "Tested on Paper"
|
||||
[bungeecord-img]: https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/bungeecord_vector.svg "Tested on BungeeCord"
|
||||
[waterfall-img]: https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/waterfall_vector.svg "Tested on Waterfall"
|
||||
@@ -42,30 +40,36 @@ AdvancedServerList supports the following platforms:
|
||||
|
||||
## Dependencies
|
||||
|
||||
| Dependency | Platforms | Required? |
|
||||
|-------------------------------------------------------------------------|----------------------|-----------|
|
||||
| [ProtocolLib]{ target="_blank" rel="noreferrer nofollow noopener" } | Spigot | Yes |
|
||||
| [PlaceholderAPI]{ target="_blank" rel="noreferrer nofollow noopener" } | Spigot, Paper | No |
|
||||
| [ViaVersion]{ target="_blank" rel="noreferrer nofollow noopener" } | Spigot, Paper | No |
|
||||
| [PAPIProxyBridge]{ target="_blank" rel="noreferrer nofollow noopener" } | BungeeCord, Velocity | No |
|
||||
| [Maintenance]{ target="_blank" rel="noreferrer nofollow noopener" } | All | No |
|
||||
/// info
|
||||
All listed dependencies are optional.
|
||||
///
|
||||
|
||||
[protocollib]: https://www.spigotmc.org/resources/1997/
|
||||
[placeholderapi]: https://www.spigotmc.org/resources/6245/
|
||||
[viaversion]: https://www.spigotmc.org/resources/19254/
|
||||
| Dependency | Platforms |
|
||||
|-------------------------------------------------------------------------|----------------------|
|
||||
| [PlaceholderAPI]{ target="_blank" rel="noreferrer nofollow noopener" } | Paper |
|
||||
| [ViaVersion]{ target="_blank" rel="noreferrer nofollow noopener" } | Paper |
|
||||
| [PAPIProxyBridge]{ target="_blank" rel="noreferrer nofollow noopener" } | BungeeCord, Velocity |
|
||||
| [Maintenance]{ target="_blank" rel="noreferrer nofollow noopener" } | All |
|
||||
|
||||
[placeholderapi]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
|
||||
[viaversion]: https://hangar.papermc.io/ViaVersion/ViaVersion
|
||||
[papiproxybridge]: https://hangar.papermc.io/William278/PAPIProxyBridge
|
||||
[maintenance]: https://hangar.papermc.io/kennytv/Maintenance
|
||||
|
||||
## Pages
|
||||
|
||||
- [Getting started](getting-started/index.md)
|
||||
- [Commands](commands/index.md)
|
||||
- [Profiles](profiles/index.md)
|
||||
- [Formatting](profiles/formatting.md)
|
||||
- [Placeholders](profiles/placeholders.md)
|
||||
- [API](api/index.md)
|
||||
- [Changelog](api/changelog.md)
|
||||
- [Reference](api/reference/index.md)
|
||||
- [Examples](examples/index.md)
|
||||
- [Migration](migration/index.md)
|
||||
- [v1.5.3 to v1.6.0](migration/v1_5_3-to-v1_6_0.md)
|
||||
- [v1.9.0 to v1.10.0](migration/v1_9_0-to-v1_10_0.md)
|
||||
- [API](api/index.md)
|
||||
- [Changelog](api/changelog.md)
|
||||
- [Javadocs](api/javadocs.md) (External site)
|
||||
- [Source Code](api/source.md) (External site)
|
||||
- [Reference](api/reference/index.md)
|
||||
- [PlaceholderAPI](placeholderapi/index.md)
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
icon: octicons/arrow-right-24
|
||||
---
|
||||
|
||||
# < 3.7.0 to 3.7.0
|
||||
|
||||
Version 3.7.0 of AdvancedServerList brought significant changes to its conditions system.
|
||||
Namely, the `conditions` option is now deprecated and planned for removal in a future release of the Plugin, and the new [`condition`](../profiles/index.md#condition) option should now be used instead.
|
||||
|
||||
## Migration
|
||||
|
||||
To migrate, all you have to do is take the entries of the old conditions option and convert them into a single String connected with `and` operators in between. See the [Example below](#example).
|
||||
|
||||
## Example
|
||||
|
||||
Here is a before and after example to help visualize the change:
|
||||
|
||||
/// tab | Before
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
conditions:
|
||||
- '${player protocol} > 763'
|
||||
- '${player isWhitelisted} == true'
|
||||
|
||||
motd:
|
||||
- 'Welcome ${player name}!'
|
||||
```
|
||||
///
|
||||
|
||||
/// tab | After
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
# The text can all be in one line. This is only for better readability.
|
||||
condition: |
|
||||
${player protocol} >= 763 and
|
||||
${player isWhitelisted}
|
||||
|
||||
motd:
|
||||
- 'Welcome ${player name}!'
|
||||
```
|
||||
///
|
||||
|
||||
/// tab | Diff View
|
||||
```diff
|
||||
priority: 0
|
||||
|
||||
-conditions:
|
||||
- - '${player protocol} >= 763'
|
||||
- - '${player isWhitelisted} == true'
|
||||
+condition: |
|
||||
+ ${player protocol} >= 763 and
|
||||
+ ${player isWhitelisted}
|
||||
```
|
||||
///
|
||||
@@ -22,82 +22,87 @@ The migration should be fairly simple. [An example](#example) is available to lo
|
||||
|
||||
Here is a before and after example to help visualize the change:
|
||||
|
||||
=== "Before"
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
|
||||
favicon: '${player name}'
|
||||
|
||||
hidePlayers: false
|
||||
|
||||
players:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
- 'Line 3'
|
||||
|
||||
playerCount: '<grey>Hover Me!'
|
||||
|
||||
xMore: 1
|
||||
```
|
||||
=== "After"
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
|
||||
favicon: '${player name}'
|
||||
|
||||
playerCount:
|
||||
hidePlayers: false
|
||||
|
||||
hover:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
- 'Line 3'
|
||||
|
||||
text: '<grey>Hover Me!'
|
||||
|
||||
extraPlayers:
|
||||
enabled: true
|
||||
amount: 1
|
||||
```
|
||||
=== "Diff view"
|
||||
```diff
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
|
||||
favicon: '${player name}'
|
||||
|
||||
-hidePlayers: false
|
||||
-
|
||||
-players:
|
||||
- - 'Line 1'
|
||||
- - 'Line 2'
|
||||
- - 'Line 3'
|
||||
-
|
||||
-playerCount: '<grey>Hover Me!'
|
||||
-
|
||||
-xMore: 1
|
||||
+playerCount:
|
||||
+ hidePlayers: false
|
||||
+
|
||||
+ hover:
|
||||
+ - 'Line 1'
|
||||
+ - 'Line 2'
|
||||
+ - 'Line 3'
|
||||
+
|
||||
+ text: '<grey>Hover Me!'
|
||||
+
|
||||
+ extraPlayers:
|
||||
+ enabled: true
|
||||
+ amount: 1
|
||||
```
|
||||
/// tab | Before
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
|
||||
favicon: '${player name}'
|
||||
|
||||
hidePlayers: false
|
||||
|
||||
players:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
- 'Line 3'
|
||||
|
||||
playerCount: '<grey>Hover Me!'
|
||||
|
||||
xMore: 1
|
||||
```
|
||||
///
|
||||
|
||||
/// tab | After
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
|
||||
favicon: '${player name}'
|
||||
|
||||
playerCount:
|
||||
hidePlayers: false
|
||||
|
||||
hover:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
- 'Line 3'
|
||||
|
||||
text: '<grey>Hover Me!'
|
||||
|
||||
extraPlayers:
|
||||
enabled: true
|
||||
amount: 1
|
||||
```
|
||||
///
|
||||
|
||||
/// tab | Diff View
|
||||
```diff
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
|
||||
favicon: '${player name}'
|
||||
|
||||
-hidePlayers: false
|
||||
-
|
||||
-players:
|
||||
- - 'Line 1'
|
||||
- - 'Line 2'
|
||||
- - 'Line 3'
|
||||
-
|
||||
-playerCount: '<grey>Hover Me!'
|
||||
-
|
||||
-xMore: 1
|
||||
+playerCount:
|
||||
+ hidePlayers: false
|
||||
+
|
||||
+ hover:
|
||||
+ - 'Line 1'
|
||||
+ - 'Line 2'
|
||||
+ - 'Line 3'
|
||||
+
|
||||
+ text: '<grey>Hover Me!'
|
||||
+
|
||||
+ extraPlayers:
|
||||
+ enabled: true
|
||||
+ amount: 1
|
||||
```
|
||||
///
|
||||
@@ -15,89 +15,94 @@ To migrate all you have to do is use the new `profiles` option and add separate
|
||||
|
||||
Here is a before and after example to help visualize the change:
|
||||
|
||||
=== "Before"
|
||||
```yaml
|
||||
priority: 0
|
||||
/// tab | Before
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
motds:
|
||||
- |-
|
||||
Line 1
|
||||
Line 2
|
||||
- |-
|
||||
Line A
|
||||
Line B
|
||||
|
||||
favicon: '${player name}'
|
||||
motds:
|
||||
- |-
|
||||
Line 1
|
||||
Line 2
|
||||
- |-
|
||||
Line A
|
||||
Line B
|
||||
|
||||
playerCount:
|
||||
hidePlayers: false
|
||||
players:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
- 'Line 3'
|
||||
text: '<grey>Hover Me!'
|
||||
extraPlayers:
|
||||
enabled: false
|
||||
amount: 0
|
||||
```
|
||||
=== "After"
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
profiles:
|
||||
# You can also use motd: ['Line 1', 'Line 2']
|
||||
- motd:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
# You can also use motd: ['Line A', 'Line B']
|
||||
- motd:
|
||||
- 'Line A'
|
||||
- 'Line B'
|
||||
|
||||
favicon: '${player name}'
|
||||
|
||||
playerCount:
|
||||
hidePlayers: false
|
||||
players:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
- 'Line 3'
|
||||
text: '<grey>Hover Me!'
|
||||
extraPlayers:
|
||||
enabled: false
|
||||
amount: 0
|
||||
```
|
||||
=== "Diff view"
|
||||
```diff
|
||||
priority: 0
|
||||
favicon: '${player name}'
|
||||
|
||||
-motds:
|
||||
- - |-
|
||||
- Line 1
|
||||
- Line 2
|
||||
- - |-
|
||||
- Line A
|
||||
- Line B
|
||||
+profiles:
|
||||
+ # You can also use motd: ['Line 1', 'Line 2']
|
||||
+ - motd:
|
||||
+ - 'Line 1'
|
||||
+ - 'Line 2'
|
||||
+ # You can also use motd: ['Line A', 'Line B']
|
||||
+ - motd:
|
||||
+ - 'Line A'
|
||||
+ - 'Line B'
|
||||
|
||||
favicon: '${player name}'
|
||||
|
||||
playerCount:
|
||||
hidePlayers: false
|
||||
players:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
- 'Line 3'
|
||||
text: '<grey>Hover Me!'
|
||||
extraPlayers:
|
||||
enabled: false
|
||||
amount: 0
|
||||
```
|
||||
playerCount:
|
||||
hidePlayers: false
|
||||
players:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
- 'Line 3'
|
||||
text: '<grey>Hover Me!'
|
||||
extraPlayers:
|
||||
enabled: false
|
||||
amount: 0
|
||||
```
|
||||
///
|
||||
|
||||
/// tab | After
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
profiles:
|
||||
# You can also use motd: ['Line 1', 'Line 2']
|
||||
- motd:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
# You can also use motd: ['Line A', 'Line B']
|
||||
- motd:
|
||||
- 'Line A'
|
||||
- 'Line B'
|
||||
|
||||
favicon: '${player name}'
|
||||
|
||||
playerCount:
|
||||
hidePlayers: false
|
||||
players:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
- 'Line 3'
|
||||
text: '<grey>Hover Me!'
|
||||
extraPlayers:
|
||||
enabled: false
|
||||
amount: 0
|
||||
```
|
||||
///
|
||||
|
||||
/// tab | Diff View
|
||||
```diff
|
||||
priority: 0
|
||||
|
||||
-motds:
|
||||
- - |-
|
||||
- Line 1
|
||||
- Line 2
|
||||
- - |-
|
||||
- Line A
|
||||
- Line B
|
||||
+profiles:
|
||||
+ # You can also use motd: ['Line 1', 'Line 2']
|
||||
+ - motd:
|
||||
+ - 'Line 1'
|
||||
+ - 'Line 2'
|
||||
+ # You can also use motd: ['Line A', 'Line B']
|
||||
+ - motd:
|
||||
+ - 'Line A'
|
||||
+ - 'Line B'
|
||||
|
||||
favicon: '${player name}'
|
||||
|
||||
playerCount:
|
||||
hidePlayers: false
|
||||
players:
|
||||
- 'Line 1'
|
||||
- 'Line 2'
|
||||
- 'Line 3'
|
||||
text: '<grey>Hover Me!'
|
||||
extraPlayers:
|
||||
enabled: false
|
||||
amount: 0
|
||||
```
|
||||
///
|
||||
@@ -13,15 +13,16 @@ AdvancedServerList provides support for [PlaceholderAPI] placeholders to be used
|
||||
The below listed placeholders can be used through PlaceholderAPI in other plugins.
|
||||
Note that the values depend on the player it is used for, as AdvancedServerList will try and get a matching [Server List Profile](../profiles/index.md) to display values from.
|
||||
|
||||
| Placeholder | Description |
|
||||
|------------------------------|---------------------------------------------------------------------------------------------------------|
|
||||
| `%asl_favicon%` | Gives the value of `favicon` from a matching Profile. |
|
||||
| `%asl_extra_players_max%` | Gives the value of `playerCount -> extraPlayers -> amount` from a matching Profile. Can return `null`. |
|
||||
| `%asl_motd%` | Gives the value of `motd` in the matching Profile as a single String. |
|
||||
| `%asl_playercount_hover%` | Gives the value of `playerCount -> hover` from a matching Profile as a single String. |
|
||||
| `%asl_playercount_text%` | Gives the value of `playerCount -> text` from a matching Profile. |
|
||||
| `%asl_players_max%` | Gives the value of `playerCount -> maxPlayers -> amount` from a matching Profile. Can return `null`. |
|
||||
| `%asl_players_max_modified%` | Returns the output of `${server playersMax}`. |
|
||||
| Placeholder | Description |
|
||||
|----------------------------------|--------------------------------------------------------------------------------------------------------|
|
||||
| `%asl_favicon%` | Gives the value of `favicon` from a matching Profile. |
|
||||
| `%asl_extra_players_max%` | Gives the value of `playerCount -> extraPlayers -> amount` from a matching Profile. Can return `null`. |
|
||||
| `%asl_motd%` | Gives the value of `motd` in the matching Profile as a single String. |
|
||||
| `%asl_playercount_extraplayers%` | Gives the value of `playerCount -> extraPlayers -> amount` from a matching Profile. Can return `null`. |
|
||||
| `%asl_playercount_hover%` | Gives the value of `playerCount -> hover` from a matching Profile as a single String. |
|
||||
| `%asl_playercount_maxplayers%` | Gives the value of `playerCount -> maxPlayers -> amount` from a matching profile. Can return `null`. |
|
||||
| `%asl_playercount_text%` | Gives the value of `playerCount -> text` from a matching Profile. |
|
||||
| `%asl_server_playersmax%` | Gives the output of `${server playersMax}` |
|
||||
|
||||
## Using Placeholders in Server List profiles
|
||||
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
---
|
||||
icon: octicons/file-code-24
|
||||
---
|
||||
|
||||
Expressions are part of a Server List Profile's condition system and allows you to define when a profile should and should not be displayed.
|
||||
|
||||
This page covers what the Expression system of AdvancedServerList offers and can do.
|
||||
|
||||
## Content
|
||||
|
||||
- [Types](#types)
|
||||
- [Literals](#literals)
|
||||
- [Numbers](#numbers)
|
||||
- [Strings](#strings)
|
||||
- [Booleans](#booleans)
|
||||
- [Placeholders](#placeholders)
|
||||
- [Binary Operators](#binary-operators)
|
||||
- [Parenthesis](#parenthesis)
|
||||
- [Negation](#negation)
|
||||
- [Credits](#credits)
|
||||
|
||||
## Types
|
||||
|
||||
An expression contains different types of components that are evaluated to return a boolean output of either `true` or `false`.
|
||||
Depending on the type(s) will the output be differently understood and handled.
|
||||
|
||||
### Literals
|
||||
|
||||
The following cases are considered literal values:
|
||||
|
||||
#### Numbers
|
||||
|
||||
Any number is considered an expression, meaning the below examples are considered valid:
|
||||
|
||||
```
|
||||
0
|
||||
1000
|
||||
-7
|
||||
47.2
|
||||
```
|
||||
|
||||
#### Strings
|
||||
|
||||
A String in single or double quotes is a valid expression.
|
||||
|
||||
/// warning | Important
|
||||
Specific keywords will be treated as [Binary Operators](#binary-operators) even if they are part of a word.
|
||||
As an example, `Sand` would cause the expression engine to see `S AND` due to parts of the word matching `and`.
|
||||
|
||||
To avoid this is it very important to always surround Strings with single or double quotes, as that tells the expression engine to treat as a String.
|
||||
///
|
||||
|
||||
```
|
||||
"Hello World!"
|
||||
""
|
||||
```
|
||||
|
||||
#### Booleans
|
||||
|
||||
Strings `true` and `false` are treated as boolean literals.
|
||||
|
||||
### Placeholders
|
||||
|
||||
Any [placeholder](placeholders.md) is a valid expression.
|
||||
|
||||
```
|
||||
${player protocol}
|
||||
${player name}
|
||||
|
||||
${server playersOnline}
|
||||
${server host}
|
||||
```
|
||||
|
||||
### Binary Operators
|
||||
|
||||
`<expression> <binary operator> <expression>` is a valid expression.
|
||||
|
||||
The following binary operators can be used for boolean evaluation:
|
||||
|
||||
| Operator | True if |
|
||||
|----------------------------------|-------------------------------------------------------------------------------------------------------------|
|
||||
| `and` / `&&` | Both expressions return true. |
|
||||
| `or` / <code>||</code> | Either expression returns true. |
|
||||
| `==` / `=` | Both expressions are equal (Case sensitive). |
|
||||
| `~=` | Both expressions are equal (Not Case sensitive). |
|
||||
| `!=` | Both expressions are not equal (Case sensitive). |
|
||||
| `!~` | Both expressions are not equal (Not case sensitive). |
|
||||
| <code>|-</code> | Left expression starts with right expression. |
|
||||
| <code>-|</code> | Left expression ends with right expression. |
|
||||
| `<-` | Left expression contains right expression. |
|
||||
| `<` | Left expression is less than the right expression. Strings use their text length as number. |
|
||||
| `<=` | Left expression is less than, or equal to, the right expression. Strings use their text length as number. |
|
||||
| `>` | Left expression is larger than the right expression. Strings use their text length as number. |
|
||||
| `>=` | Left expression is larger than, or equal to, the right expression. Strings use their text length as number. |
|
||||
|
||||
Additionally can these additional binary operators used for specific actions:
|
||||
|
||||
| Operator | Semantic |
|
||||
|----------|-----------------------------------------------------------------------------|
|
||||
| `.` | Concatenates (merges) two Strings |
|
||||
| `+` | Adds two numbers. Strings use their text length as number. |
|
||||
| `-` | Subtracts one number from another. Strings use their text length as number. |
|
||||
| `*` | Multiplies two numbers. Strings use their text length as number. |
|
||||
| `/` | Divides one number by another. Strings use their text length as number. |
|
||||
|
||||
### Parenthesis
|
||||
|
||||
`( <expression> )` is a valid expression.
|
||||
|
||||
Parenthesis can be used to prevent ambiguities.
|
||||
|
||||
### Negation
|
||||
|
||||
`!` can be used to negate boolean expressions.
|
||||
|
||||
```
|
||||
!${player isWhitelisted}
|
||||
```
|
||||
|
||||
## Credits
|
||||
|
||||
This page, including examples used, was adobted from the BungeeTabListPlus wiki.
|
||||
The original wiki page can be found here: https://github.com/CodeCrafter47/BungeeTabListPlus/wiki/Expressions
|
||||
@@ -6,14 +6,15 @@ icon: octicons/pencil-24
|
||||
|
||||
All text options, with exception of [`Conditions`](../index.md#conditions), allow the usage of formatting options using [MiniMessage].
|
||||
|
||||
!!! info "Online Tool"
|
||||
The devs of the Adventure library provide a handy online tool to create the right formatting codes to display the text properly.
|
||||
You can find the tool at https://webui.advntr.dev/
|
||||
/// info | Online Tool
|
||||
The devs of the Adventure library provide a handy online tool to create the right formatting codes to display the text properly.
|
||||
You can find the tool at https://webui.advntr.dev/
|
||||
///
|
||||
|
||||
## Before starting
|
||||
|
||||
Please make sure to surround your text with either single quotes (`'`) or double quotes (`"`) should they start with a color or formatting code.
|
||||
Not surrounding these lines with (double) quotes will make the YAML parser Configurate treat them as something other than a String.
|
||||
Please make sure to surround your text with either single quotes (`'`) or double quotes (`"`).
|
||||
This avoids possible issues where the YAML parser would treat lines starting with specific characters as special options (i.e. `<` would be treated as a scolar value).
|
||||
|
||||
```yaml title="Wrong formatting"
|
||||
motd:
|
||||
|
||||
+252
-208
@@ -2,300 +2,344 @@
|
||||
icon: octicons/note-24
|
||||
---
|
||||
|
||||
# Profiles { #profiles-settings }
|
||||
# Profiles { #profiles-file }
|
||||
|
||||
AdvancedServerList allows the creation of multiple profiles.
|
||||
A profile is a single YAML file located in the plugin's `profiles` directory containing multiple settings including [Conditions](#conditions) and [Priority](#priority).
|
||||
AdvancedServerList allows you to create multiple so called Server List Profiles.
|
||||
A Server List Profile is a YAML file located in the plugin's `profiles` folder. Each Server List Profile allows you to modify one or multiple aspects of your server's display in a Multiplayer Server list.
|
||||
|
||||
!!! info "Important"
|
||||
In order for a profile to be considered "valid" by AdvancedServerList will it need to meet the following conditions:
|
||||
|
||||
- Have a [`Priority`](#priority) set to a valid, whole number (i.e. `1`)
|
||||
- Have **at least one** of the following options set:
|
||||
- [`Profiles`](#profiles) with at least one entry containing one of the below option
|
||||
- [`Motd`](#motd) set with at least one line of text
|
||||
- [`Favicon`](#favicon) set with a non-empty String
|
||||
- [`HidePlayers`](#hideplayers) set to `true`
|
||||
- [`Hover`](#hover) set with at least one line of text
|
||||
- [`Text`](#text) set with a non-empty String
|
||||
Additionally can [Conditions](#condition) and a [Priority](#priority) be set to set when a specific profile should be displayed to a player.
|
||||
|
||||
## Required Options
|
||||
|
||||
For a Server List Profile to be valid, will it require the following options to be set:
|
||||
|
||||
- A valid [`priority`](#priority) option with a single, whole number.
|
||||
- **At least** one of the following options:
|
||||
- [`profiles`](#profiles) with at least one of the below options set.
|
||||
- [`motd`](#motd) with at least one line to display.
|
||||
- [`favicon`](#favicon) with a non-empty String.
|
||||
- [`playerCount -> hidePlayers`](#hideplayers) with value `true`.
|
||||
- [`playerCount -> hover`](#hover) with at least one line to display.
|
||||
- [`playerCount -> text`](#text) with a non-empty String.
|
||||
|
||||
## Priority
|
||||
|
||||
The priority option determines the order in which the profiles are checked by AdvancedServerList, starting with the highest number.
|
||||
The Priority option allows you to define what Server List Profile should be chosen first.
|
||||
The plugin will go highest value to lowest value and will select the first Profile that has a [`condition`](#condition) returning `true`.
|
||||
|
||||
It will go through each file until it finds one with [`conditions`](#conditions) returning true (Default if no conditions are set).
|
||||
This means that a profile with no conditions and a priority of `1` will be used before a profile with a condition and priority `0` even if the player is meeting the condition.
|
||||
Should AdvancedServerList not find any profile with a positive condition will it not modify the server list for the players.
|
||||
|
||||
## Conditions
|
||||
/// note
|
||||
It is important to note that should no [`condition`](#condition) option be set will it default to `true`, meaning that a profile with priority 1 and no condition will be chosen over a profile with priority 0 and a condition, even if said condition also returns true.
|
||||
///
|
||||
|
||||
A list of conditions can be set that need to be met in order to have this profile shown to the player.
|
||||
[Placeholders](formatting.md#placeholders) can be used to further customize the conditions (PlaceholderAPI placeholders are **not** supported).
|
||||
## Condition
|
||||
|
||||
Only when **all** conditions defined return true will the profile be displayed.
|
||||
The `condition` option allows you to define specific requirements that need to be met to display the profile in question.
|
||||
Not setting this option, or setting it to an empty String (`condition: ''`), will result in `true` being returned.
|
||||
|
||||
You can remove this option, or set it to an empty list (`conditions: []`) to always return true.
|
||||
The condition option can hold one or multiple expressions. The Expression system is explained on the [Expressions page](expressions.md).
|
||||
|
||||
## Conditions :octicons-trash-24:{ style="color: #FF5252;" title="Deprecated" }
|
||||
|
||||
<!-- admo:deprecated Deprecated in favour of the new condition option. Will be removed in a future version. -->
|
||||
|
||||
The `conditions` option - not to be confused with the new [`condition`](#condition) option - allows you to define one or multiple conditions/expressions that all need to return `true` in order for the profile to be used.
|
||||
Not setting this option, or setting it to an empty list (`conditions: []`), will result in `true` being returned.
|
||||
|
||||
Each condition can use [placeholders](placeholders.md) to further customize it. PlaceholderAPI placeholders are **not** supported!
|
||||
|
||||
### Operands
|
||||
|
||||
The following operants are available and can be used in the conditions.
|
||||
<!-- admo:warning Each condition can only hold one operand -->
|
||||
|
||||
<!-- admo:warning Only one operant can be used per condition! -->
|
||||
Each condition can use operands to compare values with each other.
|
||||
Note that if Operands are used that compare sizes (i.e. `>`) while the values are Text and not numbers will the text length be used as number.
|
||||
|
||||
| Operand | Description |
|
||||
|---------|------------------------------------------------------------------------|
|
||||
| `<` | Checks if the left value is less than the right one.[^1] |
|
||||
| `<=` | Checks if the left value is less than or equal to the right one.[^1] |
|
||||
| `>` | Checks if the left value is more than the right one.[^1] |
|
||||
| `>=` | Checks if the left value is more than or equal to the right one.[^1] |
|
||||
| `=` | Checks if the left value is equal to the right one. |
|
||||
| `!=` | Checks if the left value is not equal to the right one. |
|
||||
| `~=` | Checks if the left value is equal to the right one, ignoring case. |
|
||||
| `!~` | Checks if the left value is not equal to the right one, ignoring case. |
|
||||
|
||||
[^1]:
|
||||
Should the provided value not be a number, will AdvancedServerList use the text length to compare.
|
||||
Example: `SomeString > String` would be translated to `10 > 6`.
|
||||
| Operand | What it does |
|
||||
|---------|----------------------------------------------------------------------------|
|
||||
| `<` | Returns true if the left value is less than the right value. |
|
||||
| `<=` | Returns true if the left value is less than, or equal to, the right value. |
|
||||
| `>` | Returns true if the left value is more than the right value. |
|
||||
| `>=` | Returns true if the left value is less than, or equal to, the right value. |
|
||||
| `=` | Returns true if both values are equal (Case sensitive). |
|
||||
| `!=` | Returns true if both values are not equal (Case sensitive). |
|
||||
| `~=` | Returns true if both values are equal (Not case sensitive). |
|
||||
| `!~` | Returns true if both values are not equal (Not case sensitive). |
|
||||
|
||||
## Profiles
|
||||
|
||||
<!-- admo:warning Priority and Conditions can NOT be used within profiles -->
|
||||
The `profile` option allows you to define a list of all other options, with the exception of [`priority`](#priority), [`condition`](#condition) or itself.
|
||||
|
||||
The `profiles` option allows you to set multiple MOTDs, player counts, etc. which the plugin would randomly choose from.
|
||||
If an option such as motd is not present in an entry will it check the file for the option and use that if present.
|
||||
When multiple entries are defined will AdvancedServerList randomly select one.
|
||||
Should an option exist in the file itself (i.e. [`motd`](#motd)) but not in the selected profiles entry will it be used. This allows you to randomize only one aspect of a Server List Profile while keeping all other options the same.
|
||||
|
||||
??? example "Example"
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
profiles:
|
||||
- motd:
|
||||
- '<rainbow>Line 1</rainbow>'
|
||||
- '<rainbow:!>Line 2</rainbow>'
|
||||
playerCount:
|
||||
text: '<green><bold>Awesome!'
|
||||
- playerCount:
|
||||
text: '<yellow><bold>Also Awesome!'
|
||||
|
||||
motd:
|
||||
- '<rainbow:2>Line A</rainbow>'
|
||||
- '<rainbow:!2>Line B</rainbow>'
|
||||
```
|
||||
<div class="result">
|
||||
|
||||
{ loading="lazy" }
|
||||
{ loading="lazy" }
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
</div>
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
profiles:
|
||||
- motd: # You can also use ['<rainbow>Line1</rainbow>','<rainbow:!>Line 2</rainbow>']
|
||||
- '<rainbow>Line 1</rainbow>'
|
||||
- '<rainbow:!>Line 2</rainbow>'
|
||||
playerCount:
|
||||
text: '<green><bold>Awesome!'
|
||||
- playerCount:
|
||||
text: '<yellow><bold>Also Awesome!'
|
||||
|
||||
# This MOTD is used when the second profiles entry is selected.
|
||||
motd:
|
||||
- '<rainbow:2>Line A</rainbow>'
|
||||
- '<rainbow:!2>Line B</rainbow>'
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
## Motd
|
||||
|
||||
The motd option allows to set up to two lines to be displayed in an MOTD.
|
||||
Normal colour and formatting codes such as `<aqua>` or `<bold>` are supported. On 1.16 and newer can you also use HEX colours using either `<#rrggbb>` or `<color:#rrggbb>`.
|
||||
The `motd` option allows you to alter the "Message of the day" that is being displayed on a server in the multiplayer screen.
|
||||
Please see the [Formatting](formatting.md) for all supported formatting options.
|
||||
|
||||
If you want to display multiple MOTDs will you need to use the [`Profiles` option](#profiles)
|
||||
Multiple, randomly selected, MOTDs can be displayed by using the [`profiles`](#profiles) option.
|
||||
|
||||
??? example "Example"
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- '<rainbow:2>Rainbow Gradients</rainbow>'
|
||||
- '<rainbow:!2>|||||||||||||||||||||||||||||||||||||</rainbow>'
|
||||
```
|
||||
<div class="result">
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
{ loading="lazy" }
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
</div>
|
||||
motd:
|
||||
- '<rainbow:2>Rainbow Gradient</rainbow>'
|
||||
- '<rainbow:!2>|||||||||||||||||||||||||||||||||||||</rainbow>'
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
## Favicon
|
||||
|
||||
The favicon option allows you to customize the favicon and display one or multiple different images.
|
||||
<!-- admo:info Images will be resized to 64x64 pixels. -->
|
||||
|
||||
This option currently supports the following values:
|
||||
The `favicon` option can be used to define an image to display in the server list.
|
||||
|
||||
- A URL pointing to a `64x64` PNG image.
|
||||
- A name with `.png` extension that matches a PNG file in the `favicons` folder.
|
||||
- `${player uuid}` (or alternatively `${player name}`) to display the head of the player. The UUID/Name resolving is handled by https://mc-heads.net
|
||||
The Value can be one of three possible options, each being checked for in order:
|
||||
|
||||
Please note that AdvancedServerList will rescale the image to be 64x64 pixels, so be sure to provide images at that particular scale.
|
||||
- A URL pointing to an image file. The URL needs to start with `https://` to work.
|
||||
- A PNG filename, including `.png` file extension, matching a PNG file in the `favicons` folder.
|
||||
- A player name or UUID, or a [placeholder](placeholders.md) that resolves into one.
|
||||
|
||||
??? example "Example"
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# We use just colour to hide the MOTD
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
# Player is Andre_601
|
||||
favicon: ${player uuid}
|
||||
```
|
||||
<div class="result">
|
||||
Note that for the name/UUID, the site https://mc-heads.net is being used.
|
||||
Use the URL option with the `${player uuid}` placeholder if you want to use another service.
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
{ loading="lazy" }
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
</div>
|
||||
# Hides the MOTD for demonstration purposes
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
# Placeholder resolves to UUID of Andre_601
|
||||
favicon: '${player uuid}'
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
## PlayerCount
|
||||
|
||||
The `playerCount` option contains multiple different options all about the Player count itself.
|
||||
The `playerCount` option contains various other options that are used to modify the player count (The text next to the ping icon that shows the online and max players of a server).
|
||||
|
||||
### HidePlayers
|
||||
|
||||
Boolean option to set whether AdvancedServerList should hide the player count or not. When set to `true` will the player count be replaced with `???`.
|
||||
Additionally will the [`Text`](#text) and [`Hover`](#hover) option be ignored.
|
||||
The `playerCount -> hidePlayers` option takes a boolean (`true` or `false`) to set whether the player count should be hidden or not.
|
||||
|
||||
??? example "Example"
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# We use just colour to hide the MOTD
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
hidePlayers: true
|
||||
```
|
||||
<div class="result">
|
||||
When set to true will the player count be replaced with `???`.
|
||||
In addition are the [`playerCount -> text`](#text) and [`playerCount -> hover`](#hover) options ignored.
|
||||
|
||||
{ loading="lazy" }
|
||||
If you want to not show any text at all, set this option to `false` (or remove it) and instead use the [`playerCount -> text`](#text) option.
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
</div>
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# Hides the MOTD for demonstration purposes
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
hidePlayers: true
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
### Hover
|
||||
|
||||
This option allows to override the hover text usually displaying the players on the server when hovering over the player count.
|
||||
The `playerCount -> hover` option allows you to define lines of text to show when a player hovers over the player count with their cursor.
|
||||
|
||||
You can either remove this option or set to an empty list (`hover: []`) to not override the hover.
|
||||
Note that this option only accepts basic colors such as `<blue>` or `<grey>` and that HEX colors are not supported.
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
??? example "Example"
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# We use just colour to hide the MOTD
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
hover:
|
||||
- '<grey>Line 1'
|
||||
- '<aqua>Line 2'
|
||||
- '<gold>Line 3'
|
||||
```
|
||||
<div class="result">
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
{ loading="lazy" }
|
||||
# Hides the MOTD for demonstration purposes
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
</div>
|
||||
playerCount:
|
||||
hover:
|
||||
- '<grey>Line 1'
|
||||
- '<aqua>Line 2'
|
||||
- '<gold>Line 3'
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
### Text
|
||||
|
||||
This option allows to override the text usually displaying the online players and total players that can join.
|
||||
Note that AdvancedServerList will not add the `<online>/<max>` text to the player count. Instead will you need to use [`${server playersOnline}`](placeholders.md#server) and [`${server playersMax}`](placeholders.md#server)
|
||||
The `playerCount -> text` option allows you to define a custom text to display instead of the usual `<online>/<max>`.
|
||||
|
||||
!!! info "Note"
|
||||
This feature works by changing the "outdated server" message followed by altering the protocol version of the server.
|
||||
Due to this will your server appear as "outdated" to the client (Have the ping icon crossed out). This is nothing that can be changed unfortunately.
|
||||
Please take note of the following caveats:
|
||||
|
||||
To not override the player count, remove this option or set it to an empty String (`text: ''`).
|
||||
- The plugin won't automatically add the `<online>/<max>` back to the text you set. Instead you'll have to use `${server playersOnline}/${server playersMax}` to recreate this.
|
||||
- The override is done by using the "outdated server" text displayed when a client pings a server that is not compatible. This means that the ping icon will appear crossed out and your server will be seen as "outdated" by the client (When hovering over the ping icon). This can't be avoided nor fixed by the plugin.
|
||||
|
||||
??? example "Example"
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# We use just colour to hide the MOTD
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
text: '<yellow><bold>Cool text!'
|
||||
```
|
||||
<div class="result">
|
||||
If you want to not show any text, just use a single color (i.e. `text: '<grey>'`) to do so.
|
||||
|
||||
{ loading="lazy" }
|
||||
This option only supports basic colors and no HEX colors.
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
</div>
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# Hides the MOTD for demonstration purposes
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
text: '<yellow><bold>Cool text!'
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
### ExtraPlayers
|
||||
|
||||
Contains options to modify how the `<max>` number in the player count should look like.
|
||||
<!-- admo:warning Using this option overrides the output of the <code>${server playersMax}</code> placeholder (Except in condition). -->
|
||||
|
||||
<!-- admo:warning Using this option will modify the `${server playersMax}` placeholder (Except when used in conditions) -->
|
||||
The `playerCount -> extraPlayers` option contains settings for the "extra players" feature, which adds X to the current online player count and sets it as the server's max player count.
|
||||
|
||||
#### Enabled { #extraplayers-enabled }
|
||||
|
||||
Boolean option to set whether the extra players feature should be used or not.
|
||||
When set to `true` will the max amount of players be modified by taking the current amount of online players, add [`Amount`](#amount) more to it and use it.
|
||||
Enables the extraPlayers feature.
|
||||
Use the [`playerCount -> extraPlayers -> amount`](#extraplayers-amount) option to set how much to add to the max players count.
|
||||
|
||||
#### Amount { #extraplayers-amount }
|
||||
|
||||
Sets the number to add to the current online players to then use as the new max players count.
|
||||
<!-- admo:info This option does nothing when <code>playerCount -> hidePlayers</code> is enabled. -->
|
||||
|
||||
As an example, setting this to `1` while `10` players are online will display `11`, while `-1` would display `9`.
|
||||
The `playerCount -> extraPlayers -> amount` option defines how much should be added to the current online player count to then use as max player count.
|
||||
|
||||
??? example "Example"
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# We use just colour to hide the MOTD
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
extraPlayers:
|
||||
enabled: true
|
||||
amount: 1
|
||||
```
|
||||
<div class="result">
|
||||
Example: Setting this option to `1` while currently 10 players are online will result in `10/11` being displayed on the player count (Assuming it is not being overriden by the [`playerCount -> text`](#text) option).
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
{ loading="lazy" }
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
</div>
|
||||
# Hides the MOTD for demonstration purposes
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
extraPlayers:
|
||||
enabled: true
|
||||
amount: 1
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
### MaxPlayers
|
||||
|
||||
Contains options to set the max number of players allowed to join the server. This has only a visual effect and won't actually influence how many players can join your server.
|
||||
<!-- admo:info This feature is ignored should <code>playerCount -> extraPlayers</code> be enabled. -->
|
||||
<!-- admo:warning Using this option overrides the output of the <code>${server playersMax}</code> placeholder (Except in condition). -->
|
||||
|
||||
Note that this feature is ignored should [`extraPlayers`](#extraplayers) be enabled.
|
||||
|
||||
In case [`hidePlayers`](#hideplayers) is enabled will the max player count not be displayed, but still changed by this option.
|
||||
Should [`text`](#text) be set to a non-empty String will the max player count only be displayed when `${server playersMax}` is used.
|
||||
|
||||
<!-- admo:warning Using this option will modify the `${server playersMax}` placeholder (Except when used in conditions) -->
|
||||
The `playerCount -> maxPlayers` option is similar in nature to the [`playerCount -> extraPlayers`](#extraplayers) option, with the difference that the number set is being used as the max player count, instead of adding it together with the online player count first.
|
||||
|
||||
#### Enabled { #maxplayers-enabled }
|
||||
|
||||
Boolean option to set whether the max players feature should be used or not.
|
||||
When set to `true` will the value usually displaying how many players can join be changed to what you've set in the [`amount`](#maxplayers-amount) option.
|
||||
Enables the maxPlayers feature.
|
||||
Use the [`playerCount -> maxPlayers -> amount`](#maxplayers-amount) option to set the max player count itself.
|
||||
|
||||
#### Amount { #maxplayers-amount }
|
||||
|
||||
Sets the number to display as the max number of players allowed to join your server.
|
||||
Note that this will also affect the `${server playersMax}` placeholder, except when it is used inside conditions.
|
||||
<!-- admo:info This option does nothing when <code>playerCount -> hidePlayers</code> is enabled. -->
|
||||
|
||||
??? example "Example"
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# We use just colour to hide the MOTD
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
maxPlayers:
|
||||
enabled: true
|
||||
amount: -1
|
||||
```
|
||||
<div class="result">
|
||||
The `playerCount -> maxPlayers -> amount` option defines the number to use as the server's max players count.
|
||||
Unlike the [`playerCount -> extraPlayers -> amount`](#extraplayers-amount) option does this one not first add the current online player count to the number to then set.
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
{ loading="lazy" }
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
</div>
|
||||
# Hides the MOTD for demonstration purposes
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
maxPlayers:
|
||||
enabled: true
|
||||
amount: -1
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
@@ -21,9 +21,9 @@ These placeholders use the player who pinged the server, to return values. They
|
||||
| `${player protocol}` | The protocol version of the player. | All | No |
|
||||
| `${player uuid}` | The UUID of the player. | All | Yes[^3] |
|
||||
| `${player version}` | The protocol version of the player as readable MC version. | Velocity | No |
|
||||
| `${player hasPlayedBefore}` | Boolean for whether the player has played on the server before. | Spigot/Paper | Yes |
|
||||
| `${player isBanned}` | Boolean for whether the player has been banned from the server. | Spigot/Paper | Yes |
|
||||
| `${player isWhitelisted}` | Boolean for whether the player is whitelisted on the server. | Spigot/Paper | Yes |
|
||||
| `${player hasPlayedBefore}` | Boolean for whether the player has played on the server before. | Paper | Yes |
|
||||
| `${player isBanned}` | Boolean for whether the player has been banned from the server. | Paper | Yes |
|
||||
| `${player isWhitelisted}` | Boolean for whether the player is whitelisted on the server. | Paper | Yes |
|
||||
|
||||
[^1]:
|
||||
Whether this placeholder requires the player to have joined before while AdvancedServerList was running.
|
||||
@@ -35,22 +35,22 @@ These placeholders use the player who pinged the server, to return values. They
|
||||
|
||||
These placeholders use values given by the server/proxy AdvancedServerList runs on.
|
||||
|
||||
| Placeholder | Description |
|
||||
|------------------------------|-------------------------------------------------------------------------|
|
||||
| `${server playersOnline}` | The number of players online on this proxy/server.[^4] |
|
||||
| `${server playersMax}` | The total number of players that can join this server.[^5] |
|
||||
| `${server host}` | The domain/IP the player pinged.[^6] |
|
||||
| `${server whitelistEnabled}` | Whether the whitelist is enabled or not. Only available on Spigot/Paper |
|
||||
| Placeholder | Description | Platforms |
|
||||
|------------------------------|------------------------------------------------------------|-----------|
|
||||
| `${server playersOnline}` | The number of players online on this proxy/server.[^4] | All |
|
||||
| `${server playersMax}` | The total number of players that can join this server.[^5] | All |
|
||||
| `${server host}` | The domain/IP the player pinged.[^6] | All |
|
||||
| `${server whitelistEnabled}` | Whether the whitelist is enabled or not. | Paper |
|
||||
|
||||
[^4]:
|
||||
An space-separated list of worlds (Spigot/Paper) or Servers (BungeeCord/Velocity) can be provided to display the number of players in these worlds/servers.
|
||||
Example: `${server playersOnline lobby1 lobby2}` will display the numbers of players online on the servers `lobby1` and `lobby2`.
|
||||
A comma-separated list of world (On Paper) or Server (On BungeeCord/Velocity) names can be provided to display the added numbers of players in these worlds/servers.
|
||||
**Example:** `${server playersOnline lobby1,lobby2}` will display the collective numbers of players in the servers `lobby1` and `lobby2`.
|
||||
[^5]:
|
||||
When the [`amount` option](../index.md#amount) is used will this placeholder display the modified max players count.
|
||||
The only exception is [`conditions`](../index.md#conditions) where it uses the actual max players of the server/proxy.
|
||||
Using either the [extraPlayers' `amount`](index.md#extraplayers-amount) or [maxPlayers' `amount`](index.md#maxplayers-amount) option will make this placeholder return the modified max players count.
|
||||
Only exception to this rule is when the placeholder is used in the [`condition`](index.md#condition) option in which case it returns the actual max player count of the proxy/server.
|
||||
[^6]:
|
||||
An optional server name can be provided to display the IP/Domain associated with that server. Only works on BungeeCord/Velocity.
|
||||
Example: `${server host survival}` would display the IP/Domain associated with the `survival` server.
|
||||
An optional server name can be provided to display the IP/Domain associated with that server. This only works on BungeeCord or Velocity.
|
||||
**Example:** `${server host survival}` would display the IP/Domain associated with the `survival` server.
|
||||
|
||||
## PlaceholderAPI
|
||||
|
||||
|
||||
+20
-6
@@ -29,14 +29,15 @@ theme:
|
||||
- navigation.tabs
|
||||
- navigation.tabs.sticky
|
||||
- content.code.copy
|
||||
- content.tooltips
|
||||
|
||||
icon:
|
||||
repo: 'simple/codeberg'
|
||||
admonition:
|
||||
note: 'octicons/tag-24'
|
||||
note: 'octicons/pencil-24'
|
||||
abstract: 'octicons/checklist-24'
|
||||
info: 'octicons/info-24'
|
||||
tip: 'octicons/flame-24'
|
||||
tip: 'octicons/light-bulb-24'
|
||||
success: 'octicons/check-24'
|
||||
question: 'octicons/question-24'
|
||||
warning: 'octicons/alert-24'
|
||||
@@ -72,7 +73,6 @@ plugins:
|
||||
- pagenav-generator
|
||||
|
||||
markdown_extensions:
|
||||
- markdown.extensions.admonition:
|
||||
- markdown.extensions.toc:
|
||||
permalink: true
|
||||
- markdown.extensions.attr_list:
|
||||
@@ -84,11 +84,25 @@ markdown_extensions:
|
||||
- pymdownx.highlight:
|
||||
- pymdownx.magiclink:
|
||||
- pymdownx.superfences:
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
- pymdownx.details:
|
||||
- pymdownx.snippets:
|
||||
base_path: docs/.snippets
|
||||
- pymdownx.blocks.admonition:
|
||||
types:
|
||||
- note
|
||||
- abstract
|
||||
- info
|
||||
- tip
|
||||
- success
|
||||
- question
|
||||
- warning
|
||||
- failure
|
||||
- danger
|
||||
- bug
|
||||
- example
|
||||
- quote
|
||||
- pymdownx.blocks.tab:
|
||||
alternate_style: true
|
||||
- pymdownx.blocks.details:
|
||||
|
||||
hooks:
|
||||
- docs/.hooks/badges.py
|
||||
@@ -34,7 +34,7 @@
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>bukkit</artifactId>
|
||||
<artifactId>paper</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>${plugin.version}</version>
|
||||
|
||||
@@ -85,24 +85,6 @@
|
||||
<version>1.20-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.20-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-platform-bukkit</artifactId>
|
||||
<version>4.3.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
@@ -112,19 +94,19 @@
|
||||
<dependency>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
<version>2.11.4</version>
|
||||
<version>2.11.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.viaversion</groupId>
|
||||
<artifactId>viaversion-api</artifactId>
|
||||
<version>4.8.1</version>
|
||||
<version>4.9.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>AdvancedServerList-Bukkit-${plugin.version}</finalName>
|
||||
<finalName>AdvancedServerList-Paper-${plugin.version}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
@@ -135,7 +117,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<version>3.12.1</version>
|
||||
<configuration>
|
||||
<release>16</release>
|
||||
</configuration>
|
||||
+49
-19
@@ -25,41 +25,52 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.paper;
|
||||
|
||||
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
|
||||
import ch.andre601.advancedserverlist.bukkit.commands.CmdAdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.bukkit.listeners.JoinEvent;
|
||||
import ch.andre601.advancedserverlist.bukkit.listeners.LoadEvent;
|
||||
import ch.andre601.advancedserverlist.bukkit.listeners.WorldEvents;
|
||||
import ch.andre601.advancedserverlist.bukkit.logging.BukkitLogger;
|
||||
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.BukkitPlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.BukkitServerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.PAPIPlaceholders;
|
||||
import ch.andre601.advancedserverlist.bukkit.objects.WorldCache;
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
|
||||
import ch.andre601.advancedserverlist.paper.listeners.PaperPingEvent;
|
||||
import ch.andre601.advancedserverlist.paper.commands.CmdAdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.paper.listeners.LoadEvent;
|
||||
import ch.andre601.advancedserverlist.paper.logging.PaperLogger;
|
||||
import ch.andre601.advancedserverlist.paper.objects.WorldCache;
|
||||
import ch.andre601.advancedserverlist.paper.objects.placeholders.PAPIPlaceholders;
|
||||
import ch.andre601.advancedserverlist.paper.objects.placeholders.PaperPlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.paper.objects.placeholders.PaperServerPlaceholders;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.CachedServerIcon;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class PaperCore extends BukkitCore<CachedServerIcon>{
|
||||
public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon>{
|
||||
|
||||
private final PluginLogger logger = new BukkitLogger(getLogger());
|
||||
private final PluginLogger logger = new PaperLogger(this);
|
||||
|
||||
private AdvancedServerList<CachedServerIcon> core;
|
||||
private FaviconHandler<CachedServerIcon> faviconHandler = null;
|
||||
private PAPIPlaceholders<CachedServerIcon> papiPlaceholders = null;
|
||||
private PAPIPlaceholders papiPlaceholders = null;
|
||||
private WorldCache worldCache = null;
|
||||
|
||||
@Override
|
||||
public void onEnable(){
|
||||
this.core = AdvancedServerList.init(this, BukkitPlayerPlaceholders.init(), BukkitServerPlaceholders.init());
|
||||
try{
|
||||
Class.forName("io.papermc.paper.configuration.ConfigurationLoaders");
|
||||
}catch(ClassNotFoundException ignored){
|
||||
try{
|
||||
// Above class only exists since 1.19+. This is a fallback to see if an older version is used.
|
||||
Class.forName("com.destroystokyo.paper.PaperConfig");
|
||||
}catch(ClassNotFoundException ex){
|
||||
printNoPaperWarning();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.core = AdvancedServerList.init(this, new PaperPlayerPlaceholders(), new PaperServerPlaceholders());
|
||||
|
||||
if(getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
papiPlaceholders = PAPIPlaceholders.init(this);
|
||||
papiPlaceholders = new PAPIPlaceholders(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,8 +97,7 @@ public class PaperCore extends BukkitCore<CachedServerIcon>{
|
||||
|
||||
@Override
|
||||
public void loadEvents(){
|
||||
LoadEvent.init(this);
|
||||
PaperPingEvent.init(this);
|
||||
new LoadEvent(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -143,11 +153,31 @@ public class PaperCore extends BukkitCore<CachedServerIcon>{
|
||||
return "paper";
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldCache getWorldCache(){
|
||||
if(worldCache != null)
|
||||
return worldCache;
|
||||
|
||||
return (worldCache = new WorldCache());
|
||||
}
|
||||
|
||||
private void printNoPaperWarning(){
|
||||
getPluginLogger().warn("======================================================================================");
|
||||
getPluginLogger().warn("THIS SERVER DOES NOT USE PAPER OR A COMPATIBLE FORK!");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("AdvancedServerList 3.6.0 has dropped support for Spigot-based servers.");
|
||||
getPluginLogger().warn("This means that only servers using Paper or a Paper-compatible fork may work.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("Reasons for this removal:");
|
||||
getPluginLogger().warn(" - Reliance on a different plugin for core functionalities.");
|
||||
getPluginLogger().warn(" - Bad dependency loading limited to MavenCentral only.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("Please consider switching to Paper or one of the Paper-compatible forks to benefit from");
|
||||
getPluginLogger().warn("overall performance improvements amongst other things.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("AdvancedServerList will now disable itself. If you believe this was a mistake, report");
|
||||
getPluginLogger().warn("this on Codeberg: https://codeberg.org/Andre601/AdvancedServerList");
|
||||
getPluginLogger().warn("======================================================================================");
|
||||
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.paper.commands;
|
||||
|
||||
import ch.andre601.advancedserverlist.paper.PaperCore;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class CmdAdvancedServerList extends Command{
|
||||
|
||||
private final PaperCore plugin;
|
||||
|
||||
public CmdAdvancedServerList(PaperCore plugin){
|
||||
super(
|
||||
"advancedserverlist",
|
||||
"Main command of the plugin",
|
||||
"/asl [reload|help|clearCache]",
|
||||
Collections.singletonList("asl")
|
||||
);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull CommandSender sender, @NotNull String s, @NotNull String[] args){
|
||||
plugin.getCore().getCommandHandler().handle(new PaperCmdSender(sender), args);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Loaded 100 of 127 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user