Compare commits

...
55 Commits
Author SHA1 Message Date
Andre601 5df2e05a14 Fix wrong file paths for paper 2023-12-02 14:27:45 +01:00
Andre601 d4e4173cc3 Improve placeholders with world/server args 2023-12-02 13:59:56 +01:00
Andre601 562ad481c5 Bump version to 3.6.0 2023-12-02 12:43:11 +00:00
Andre601 a0ee2a4322 Merge pull request 'Remove Spigot support' (#183) from feature/remove-spigot-support into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/183
2023-12-02 12:42:30 +00:00
Andre601 2c92efdb43 Merge branch 'master' into feature/remove-spigot-support 2023-12-02 12:39:37 +00:00
Andre601 555dc9d6a5 Merge pull request 'Improve docs workflow setup' (#179) from feature/improve-docs-workflow into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/179
2023-12-02 12:39:28 +00:00
Andre601 27742c5e1b .woodpecker/publish_docs.yml aktualisiert 2023-12-02 12:39:16 +00:00
Andre601 280aeb8d2e Merge branch 'master' into feature/improve-docs-workflow 2023-12-02 12:38:49 +00:00
Andre601 92a868f0fa Merge pull request 'Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.2.3' (#185) from renovate/org.apache.httpcomponents.client5-httpclient5-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/185
2023-12-02 12:03:33 +00:00
Andre601 189ac5e09b Merge pull request 'Update dependency ch.qos.logback:logback-classic to v1.4.14' (#184) from renovate/ch.qos.logback-logback-classic-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/184
2023-12-02 12:03:13 +00:00
Andre601's Renovate Bot 833cb81d65 Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.2.3 2023-12-02 12:01:18 +00:00
Andre601's Renovate Bot ab09422da5 Update dependency ch.qos.logback:logback-classic to v1.4.14 2023-12-02 12:01:14 +00:00
Andre601 64cad6dc26 Remove Spigot from readme and docs 2023-12-01 17:00:14 +01:00
Andre601 ce78b493f4 Remove spigot from supported platforms in PlatformInfo 2023-12-01 16:58:43 +01:00
Andre601 c43048ea3f Remove Spigot support 2023-12-01 16:51:33 +01:00
Andre601 6d4d1600ab Add Getting Started page 2023-11-29 15:09:32 +01:00
Andre601 f114e99b9b Merge pull request 'Update dependency ch.qos.logback:logback-classic to v1.4.13' (#182) from renovate/ch.qos.logback-logback-classic-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/182
2023-11-29 12:06:26 +00:00
Andre601's Renovate Bot 3d587bc86d Update dependency ch.qos.logback:logback-classic to v1.4.13 2023-11-29 12:01:18 +00:00
Andre601 bd8c6be7c6 Merge pull request 'Update dependency ch.qos.logback:logback-classic to v1.4.12' (#181) from renovate/ch.qos.logback-logback-classic-1.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/181
2023-11-28 12:02:35 +00:00
Andre601's Renovate Bot b5d5d508e2 Update dependency ch.qos.logback:logback-classic to v1.4.12 2023-11-28 12:01:02 +00:00
Andre601 3001b65fe8 Merge pull request 'Update dependency mkdocs-material to v9.4.14' (#180) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/180
2023-11-27 12:08:29 +00:00
Andre601's Renovate Bot c82771db59 Update dependency mkdocs-material to v9.4.14 2023-11-27 12:01:59 +00:00
Andre601 9880836c25 Improve docs workflow setup 2023-11-25 00:32:57 +00:00
Andre601 f12ae28722 Add Source redirect for API 2023-11-25 00:19:59 +00:00
Andre601 42b0f0e94f Merge pull request 'Update dependency mkdocs-material to v9.4.12' (#178) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/178
2023-11-24 12:04:02 +00:00
Andre601's Renovate Bot 0a4b872051 Update dependency mkdocs-material to v9.4.12 2023-11-24 12:00:59 +00:00
Andre601 b1322105ed Merge pull request 'Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.2.2' (#177) from renovate/org.apache.httpcomponents.client5-httpclient5-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/177
2023-11-23 12:02:45 +00:00
Andre601 831ca57fbb Merge branch 'master' into renovate/org.apache.httpcomponents.client5-httpclient5-5.x 2023-11-23 12:02:17 +00:00
Andre601 6502639cd3 Merge pull request 'Update dependency mkdocs-material to v9.4.11' (#176) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/176
2023-11-23 12:01:54 +00:00
Andre601's Renovate Bot 5059b80db2 Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.2.2 2023-11-23 12:01:07 +00:00
Andre601's Renovate Bot ecdaf72963 Update dependency mkdocs-material to v9.4.11 2023-11-23 12:00:58 +00:00
Andre601 28e2ca69ed Merge pull request 'Update dependency mkdocs-material to v9.4.10' (#175) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/175
2023-11-19 20:40:20 +00:00
Andre601 9cad78b6e4 Merge branch 'master' into renovate/mkdocs-material-9.x 2023-11-19 21:39:40 +01:00
Andre601 af8654666b Merge pull request 'Update dependency mkdocs-glightbox to v0.3.5' (#174) from renovate/mkdocs-glightbox-0.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/174
2023-11-19 12:20:05 +00:00
Andre601's Renovate Bot 6cd474b35d Update dependency mkdocs-material to v9.4.10 2023-11-19 12:01:07 +00:00
Andre601's Renovate Bot 3802ab556c Update dependency mkdocs-glightbox to v0.3.5 2023-11-19 12:01:02 +00:00
Andre601 3a520eeaf0 Merge pull request 'Update dependency mkdocs-material to v9.4.9' (#173) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/173
2023-11-17 12:15:02 +00:00
Andre601's Renovate Bot 204f43c112 Update dependency mkdocs-material to v9.4.9 2023-11-17 12:00:45 +00:00
Andre601 fc8ed8e49e Merge pull request 'Update dependency mkdocs-material to v9.4.8' (#172) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/172
2023-11-06 12:02:13 +00:00
Andre601's Renovate Bot 56082c308b Update dependency mkdocs-material to v9.4.8 2023-11-06 12:01:06 +00:00
Andre601 205e563095 Fix wrong placeholder names. 2023-11-05 13:59:46 +00:00
Andre601 5b01940c60 Merge pull request 'Update dependency me.clip:placeholderapi to v2.11.5' (#171) from renovate/me.clip-placeholderapi-2.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/171
2023-10-29 12:05:36 +00:00
Andre601's Renovate Bot cbb087e3d1 Update dependency me.clip:placeholderapi to v2.11.5 2023-10-29 12:01:15 +00:00
Andre601 524b926244 Merge pull request 'Update dependency mkdocs-material to v9.4.7' (#170) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/170
2023-10-28 12:01:09 +00:00
Andre601's Renovate Bot 4059bbfe93 Update dependency mkdocs-material to v9.4.7 2023-10-28 12:00:43 +00:00
Andre601 9b0b69a4f4 Merge pull request 'Update maven Docker tag to v3.9.5' (#169) from renovate/maven-3.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/169
2023-10-20 12:02:12 +00:00
Andre601's Renovate Bot 10a82eb951 Update maven Docker tag to v3.9.5 2023-10-20 12:01:07 +00:00
Andre601 690f7dfaf0 Merge pull request 'Update dependency com.squareup.okhttp3:okhttp to v4.12.0' (#168) from renovate/com.squareup.okhttp3-okhttp-4.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/168
2023-10-17 12:03:39 +00:00
Andre601's Renovate Bot 6a22d20b3a Update dependency com.squareup.okhttp3:okhttp to v4.12.0 2023-10-17 12:00:59 +00:00
Andre601 b1072bb1fa Update HangarVersionUploader for latest API changes 2023-10-16 12:01:12 +02:00
Andre601 d20da91bab Remove Hangar for now 2023-10-16 11:43:54 +02:00
Andre601 17e9692028 Remove unused import 2023-10-16 11:22:37 +02:00
Andre601 45dc8a5fe6 Don't use closeable http client 2023-10-16 11:22:09 +02:00
Andre601 a237ac1ce4 Merge pull request 'Update dependency mkdocs-material to v9.4.6' (#167) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/167
2023-10-15 17:27:18 +00:00
Andre601's Renovate Bot 27e66a16b9 Update dependency mkdocs-material to v9.4.6 2023-10-15 17:01:04 +00:00
57 changed files with 1454 additions and 1639 deletions

No files matched your search

+3 -5
View File
@@ -4,12 +4,10 @@ when:
steps:
createFiles:
image: maven:3.9.4-eclipse-temurin-17
image: maven:3.9.5-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
+20 -12
View File
@@ -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
+10 -11
View File
@@ -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
@@ -104,7 +104,6 @@ You can disable this in the global bStats config file located in `/plugins/bstat
[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
@@ -1,39 +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;
import ch.andre601.advancedserverlist.bukkit.objects.WorldCache;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import org.bukkit.plugin.java.JavaPlugin;
/*
* 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();
}
@@ -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,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("======================================================================================");
}
}
@@ -1,52 +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.commands;
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;
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;
}
@Override
public boolean hasPermission(String permission){
return sender.hasPermission(permission) || sender.hasPermission("advancedserverlist.admin");
}
@Override
public void sendMsg(String msg, Object... args){
bukkitAudiences.sender(sender).sendMessage(ComponentParser.text(String.format(msg, args)).toComponent());
}
}
@@ -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);
}
}
@@ -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));
}
});
}
}
+1 -1
View File
@@ -111,7 +111,7 @@
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.11.0</version>
<version>4.12.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
@@ -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);
if(info == null)
continue;
+1 -1
View File
@@ -98,7 +98,7 @@
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.11.0</version>
<version>4.12.0</version>
<scope>provided</scope>
</dependency>
<dependency>
+4 -5
View File
@@ -48,11 +48,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
View File
@@ -1,5 +1,6 @@
nav:
- Home: index.md
- getting-started
- commands
- profiles
- examples
+273 -243
View File
@@ -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!
+10
View File
@@ -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 -->
+12 -1
View File
@@ -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();
}
+64 -61
View File
@@ -38,20 +38,28 @@
--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>');
}
.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 +68,193 @@
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);
}
+368
View File
@@ -0,0 +1,368 @@
---
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 Spigot, Paper, BungeeCord, Waterfall and Velocity, and has been tested on these platforms. It may support additional forks, but this is not guaranteed.
The plugin also supports these additional plugins. Depending on the platform they are used in is the plugin required.
- [PlaceholderAPI] - Used on the Spigot and Paper server for additional Placeholder parsing.
- - [ViaVersion] - Used on the Spigot and Paper server for additional protocol version handling.
- [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` | Spigot, Paper |
| `AdvancedServerList-BungeeCord-{version}.jar` | BungeeCord, Waterfall |
| `AdvancedServerList-Velocity-{version}.jar` | Velocity |
After you added it to your plugins folder - alongside any other dependency you may want or need - (re)start your server or proxy to enable the plugin.
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
- 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
#
# 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
View File
@@ -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)
+84 -79
View File
@@ -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
```
///
+88 -83
View File
@@ -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
```
///
+10 -9
View File
@@ -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
+6 -5
View File
@@ -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:
+171 -146
View File
@@ -7,17 +7,18 @@ icon: octicons/note-24
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).
!!! 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
/// 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
///
## Priority
@@ -63,29 +64,32 @@ The following operants are available and can be used in the conditions.
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.
??? 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">
![profiles-example-1](../assets/images/examples/profiles-example-1.jpg){ loading="lazy" }
![profiles-example-2](../assets/images/examples/profiles-example-2.jpg){ loading="lazy" }
/// details | Example
type: example
</div>
```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" markdown>
![profiles-example-1](../assets/images/examples/profiles-example-1.jpg){ loading="lazy" }
![profiles-example-2](../assets/images/examples/profiles-example-2.jpg){ loading="lazy" }
</div>
///
## Motd
@@ -94,20 +98,22 @@ Normal colour and formatting codes such as `<aqua>` or `<bold>` are supported. O
If you want to display multiple MOTDs will you need to use the [`Profiles` option](#profiles)
??? example "Example"
```yaml title="YAML file"
priority: 0
motd:
- '<rainbow:2>Rainbow Gradients</rainbow>'
- '<rainbow:!2>|||||||||||||||||||||||||||||||||||||</rainbow>'
```
<div class="result">
/// details | Example
type: example
![motd-example](../assets/images/examples/motd-example.jpg){ loading="lazy" }
```yaml title="YAML file"
priority: 0
</div>
motd:
- '<rainbow:2>Rainbow Gradients</rainbow>'
- '<rainbow:!2>|||||||||||||||||||||||||||||||||||||</rainbow>'
```
<div class="result" markdown>
![motd-example](../assets/images/examples/motd-example.jpg){ loading="lazy" }
</div>
///
## Favicon
@@ -121,23 +127,26 @@ This option currently supports the following values:
Please note that AdvancedServerList will rescale the image to be 64x64 pixels, so be sure to provide images at that particular scale.
??? 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">
/// details | Example
type: example
![hideplayers-example](../assets/images/examples/favicon-example.jpg){ loading="lazy" }
```yaml title="YAML file"
priority: 0
</div>
# We use just colour to hide the MOTD
motd:
- '<grey>'
- '<grey>'
# Player is Andre_601
favicon: ${player uuid}
```
<div class="result" markdown>
![hideplayers-example](../assets/images/examples/favicon-example.jpg){ loading="lazy" }
</div>
///
## PlayerCount
@@ -148,23 +157,26 @@ The `playerCount` option contains multiple different options all about the Playe
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.
??? 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">
/// details | Example
type: example
![hideplayers-example](../assets/images/examples/hideplayers-example.jpg){ loading="lazy" }
```yaml title="YAML file"
priority: 0
</div>
# We use just colour to hide the MOTD
motd:
- '<grey>'
- '<grey>'
playerCount:
hidePlayers: true
```
<div class="result" markdown>
![hideplayers-example](../assets/images/examples/hideplayers-example.jpg){ loading="lazy" }
</div>
///
### Hover
@@ -172,61 +184,68 @@ This option allows to override the hover text usually displaying the players on
You can either remove this option or set to an empty list (`hover: []`) to not override the hover.
??? 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">
/// details | Example
type: example
![hover-example](../assets/images/examples/hover-example.jpg){ loading="lazy" }
```yaml title="YAML file"
priority: 0
</div>
# 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" markdown>
![hover-example](../assets/images/examples/hover-example.jpg){ 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)
!!! 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.
/// 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.
///
To not override the player count, remove this option or set it to an empty String (`text: ''`).
??? 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">
/// details | Example
type: example
![hover-example](../assets/images/examples/text-example.jpg){ loading="lazy" }
```yaml title="YAML file"
priority: 0
</div>
# We use just colour to hide the MOTD
motd:
- '<grey>'
- '<grey>'
playerCount:
text: '<yellow><bold>Cool text!'
```
<div class="result" markdown>
![hover-example](../assets/images/examples/text-example.jpg){ loading="lazy" }
</div>
///
### ExtraPlayers
Contains options to modify how the `<max>` number in the player count should look like.
<!-- admo:warning Using this option will modify the `${server playersMax}` placeholder (Except when used in conditions) -->
<!-- admo:warning Using this option will modify the <code>${server playersMax}</code> placeholder (Except when used in conditions) -->
#### Enabled { #extraplayers-enabled }
@@ -239,25 +258,28 @@ Sets the number to add to the current online players to then use as the new max
As an example, setting this to `1` while `10` players are online will display `11`, while `-1` would display `9`.
??? 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">
/// details | Example
type: example
![extraplayers-example](../assets/images/examples/extraplayers-example.jpg){ loading="lazy" }
```yaml title="YAML file"
priority: 0
</div>
# We use just colour to hide the MOTD
motd:
- '<grey>'
- '<grey>'
playerCount:
extraPlayers:
enabled: true
amount: 1
```
<div class="result" markdown>
![extraplayers-example](../assets/images/examples/extraplayers-example.jpg){ loading="lazy" }
</div>
///
### MaxPlayers
@@ -268,7 +290,7 @@ Note that this feature is ignored should [`extraPlayers`](#extraplayers) be enab
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) -->
<!-- admo:warning Using this option will modify the <code>${server playersMax}</code> placeholder (Except when used in conditions) -->
#### Enabled { #maxplayers-enabled }
@@ -280,22 +302,25 @@ When set to `true` will the value usually displaying how many players can join b
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.
??? 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">
/// details | Example
type: example
![maxplayes-example](../assets/images/examples/maxplayers-example.jpg){ loading="lazy" }
```yaml title="YAML file"
priority: 0
</div>
# We use just colour to hide the MOTD
motd:
- '<grey>'
- '<grey>'
playerCount:
maxPlayers:
enabled: true
amount: -1
```
<div class="result" markdown>
![maxplayes-example](../assets/images/examples/maxplayers-example.jpg){ loading="lazy" }
</div>
///
+3 -3
View File
@@ -43,14 +43,14 @@ These placeholders use values given by the server/proxy AdvancedServerList runs
| `${server whitelistEnabled}` | Whether the whitelist is enabled or not. Only available on Spigot/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.
[^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.
**Example:** `${server host survival}` would display the IP/Domain associated with the `survival` server.
## PlaceholderAPI
+19 -6
View File
@@ -33,10 +33,10 @@ theme:
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 +72,6 @@ plugins:
- pagenav-generator
markdown_extensions:
- markdown.extensions.admonition:
- markdown.extensions.toc:
permalink: true
- markdown.extensions.attr_list:
@@ -84,11 +83,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
+3 -21
View File
@@ -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,7 +94,7 @@
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.11.4</version>
<version>2.11.5</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -124,7 +106,7 @@
</dependencies>
<build>
<finalName>AdvancedServerList-Bukkit-${plugin.version}</finalName>
<finalName>AdvancedServerList-Paper-${plugin.version}</finalName>
<resources>
<resource>
<filtering>true</filtering>
@@ -25,7 +25,6 @@
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;
@@ -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.getLogger());
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);
}
}
@@ -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;
}
}
@@ -23,9 +23,9 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.listeners;
package ch.andre601.advancedserverlist.paper.listeners;
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
import ch.andre601.advancedserverlist.paper.PaperCore;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -34,19 +34,15 @@ import org.bukkit.event.player.PlayerJoinEvent;
import java.net.InetSocketAddress;
public class JoinEvent<F> implements Listener{
public class JoinEvent implements Listener{
private final BukkitCore<F> plugin;
private final PaperCore plugin;
private JoinEvent(BukkitCore<F> plugin){
public JoinEvent(PaperCore plugin){
this.plugin = plugin;
Bukkit.getPluginManager().registerEvents(this, plugin);
}
public static <F> void init(BukkitCore<F> plugin){
new JoinEvent<>(plugin);
}
@EventHandler
public void onJoin(PlayerJoinEvent event){
InetSocketAddress address = event.getPlayer().getAddress();
@@ -23,11 +23,30 @@
*
*/
package ch.andre601.advancedserverlist.versionuploader.hangar.version;
package ch.andre601.advancedserverlist.paper.listeners;
public record Namespace(String owner, String slug){
@Override
public String toString(){
return owner() + "/" + slug();
import ch.andre601.advancedserverlist.paper.PaperCore;
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 PaperCore plugin;
public LoadEvent(PaperCore plugin){
this.plugin = plugin;
Bukkit.getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onLoad(ServerLoadEvent event){
new JoinEvent(plugin);
new PingEvent(plugin);
new WorldEvents(plugin);
// Load currently loaded worlds into the WorldCache
Bukkit.getWorlds().forEach(world -> plugin.getWorldCache().addWorld(world));
}
}
@@ -28,16 +28,15 @@ package ch.andre601.advancedserverlist.paper.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.bukkit.objects.impl.BukkitPlayerImpl;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
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.paper.PaperCore;
import ch.andre601.advancedserverlist.paper.objects.impl.PaperPlayerImpl;
import ch.andre601.advancedserverlist.paper.objects.impl.PaperServerImpl;
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
import com.destroystokyo.paper.profile.PlayerProfile;
import me.clip.placeholderapi.PlaceholderAPI;
@@ -49,7 +48,7 @@ import org.bukkit.util.CachedServerIcon;
import java.awt.image.BufferedImage;
import java.util.*;
public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon, BukkitPlayerImpl>{
public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon, PaperPlayerImpl>{
private final PaperCore plugin;
private final PaperServerListPingEvent event;
@@ -89,7 +88,7 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
}
@Override
public void setPlayers(List<String> lines, BukkitPlayerImpl player, GenericServer server){
public void setPlayers(List<String> lines, PaperPlayerImpl player, GenericServer server){
event.getPlayerSample().clear();
List<PlayerProfile> players = new ArrayList<>(lines.size());
@@ -159,7 +158,7 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
}
@Override
public String parsePAPIPlaceholders(String text, BukkitPlayerImpl player){
public String parsePAPIPlaceholders(String text, PaperPlayerImpl player){
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
@@ -172,20 +171,20 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
}
@Override
public BukkitCore<CachedServerIcon> getPlugin(){
public PluginCore<CachedServerIcon> getPlugin(){
return plugin;
}
@Override
public BukkitPlayerImpl createPlayer(CachedPlayer player, int protocol){
public PaperPlayerImpl createPlayer(CachedPlayer player, int protocol){
OfflinePlayer pl = Bukkit.getOfflinePlayer(player.getUuid());
return new BukkitPlayerImpl(pl.hasPlayedBefore() ? pl : null, player, protocol);
return new PaperPlayerImpl(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);
return new PaperServerImpl(plugin.getWorldCache().worlds(), playersOnline, playersMax, host);
}
@Override
@@ -31,19 +31,15 @@ import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class PaperPingEvent implements Listener{
public class PingEvent implements Listener{
private final PaperCore plugin;
private PaperPingEvent(PaperCore plugin){
public PingEvent(PaperCore plugin){
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public static void init(PaperCore plugin){
new PaperPingEvent(plugin);
}
@EventHandler
public void onPaperServerListPing(PaperServerListPingEvent event){
PingEventHandler.handleEvent(new PaperEventWrapper(plugin, event));
@@ -23,7 +23,7 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.listeners;
package ch.andre601.advancedserverlist.paper.listeners;
import ch.andre601.advancedserverlist.api.bukkit.events.PreServerListSetEvent;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
@@ -23,10 +23,9 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.listeners;
package ch.andre601.advancedserverlist.paper.listeners;
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
import org.bukkit.Bukkit;
import ch.andre601.advancedserverlist.paper.PaperCore;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldLoadEvent;
@@ -34,20 +33,15 @@ import org.bukkit.event.world.WorldUnloadEvent;
public class WorldEvents implements Listener{
private final BukkitCore<?> plugin;
private final PaperCore plugin;
private WorldEvents(BukkitCore<?> plugin){
public WorldEvents(PaperCore plugin){
this.plugin = plugin;
Bukkit.getPluginManager().registerEvents(this, plugin);
}
public static void init(BukkitCore<?> plugin){
new WorldEvents(plugin);
}
@EventHandler
public void onWorldLoad(WorldLoadEvent event){
plugin.getWorldCache().addWorld(event.getWorld().getName(), event.getWorld());
plugin.getWorldCache().addWorld(event.getWorld());
}
@EventHandler
@@ -23,18 +23,18 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.logging;
package ch.andre601.advancedserverlist.paper.logging;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import java.util.logging.Level;
import java.util.logging.Logger;
public class BukkitLogger implements PluginLogger{
public class PaperLogger implements PluginLogger{
private final Logger logger;
public BukkitLogger(Logger logger){
public PaperLogger(Logger logger){
this.logger = logger;
}
@@ -23,7 +23,7 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.objects;
package ch.andre601.advancedserverlist.paper.objects;
import org.bukkit.World;
@@ -36,15 +36,15 @@ public record WorldCache(Map<String, World> worlds){
this(new HashMap<>());
}
public boolean containsWorld(String key){
return worlds().containsKey(key);
public boolean containsWorld(String name){
return this.worlds.containsKey(name);
}
public void addWorld(String key, World world){
worlds().put(key, world);
public void addWorld(World world){
this.worlds.put(world.getName(), world);
}
public void removeWorld(String key){
worlds().remove(key);
public void removeWorld(String name){
this.worlds.remove(name);
}
}
@@ -23,31 +23,30 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.objects.impl;
package ch.andre601.advancedserverlist.paper.objects.impl;
import ch.andre601.advancedserverlist.api.bukkit.objects.BukkitPlayer;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayerImpl;
import org.bukkit.OfflinePlayer;
public class BukkitPlayerImpl extends GenericPlayerImpl implements BukkitPlayer{
public class PaperPlayerImpl extends GenericPlayerImpl implements BukkitPlayer{
private final OfflinePlayer player;
private boolean playedBefore = false;
private boolean banned = false;
private boolean whitelisted = false;
public BukkitPlayerImpl(OfflinePlayer player, CachedPlayer cachedPlayer, int protocol){
public PaperPlayerImpl(OfflinePlayer player, CachedPlayer cachedPlayer, int protocol){
this.player = player;
this.name = player == null ? cachedPlayer.getName() : player.getName();
this.protocol = protocol;
this.uuid = player == null ? cachedPlayer.getUuid() : player.getUniqueId();
if(player == null)
return;
this.playedBefore = player.hasPlayedBefore();
this.banned = player.isBanned();
this.whitelisted = player.isWhitelisted();
@@ -23,15 +23,14 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.objects.impl;
package ch.andre601.advancedserverlist.paper.objects.impl;
import ch.andre601.advancedserverlist.api.bukkit.objects.BukkitServer;
import org.bukkit.World;
import java.util.Map;
public record BukkitServerImpl(Map<String, World> worlds, int playersOnline, int playersMax, String host) implements BukkitServer{
public record PaperServerImpl(Map<String, World> worlds, int playersOnline, int playersMax, String host) implements BukkitServer {
@Override
public Map<String, World> getWorlds(){
return worlds;
@@ -23,23 +23,19 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.objects.placeholders;
package ch.andre601.advancedserverlist.paper.objects.placeholders;
import ch.andre601.advancedserverlist.api.bukkit.objects.BukkitPlayer;
import ch.andre601.advancedserverlist.api.bukkit.objects.BukkitServer;
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.bukkit.BukkitCore;
import ch.andre601.advancedserverlist.bukkit.objects.impl.BukkitPlayerImpl;
import ch.andre601.advancedserverlist.bukkit.objects.impl.BukkitServerImpl;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileManager;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import ch.andre601.advancedserverlist.spigot.listeners.ProtocolLibEvents;
import com.comphenix.protocol.ProtocolLibrary;
import ch.andre601.advancedserverlist.paper.PaperCore;
import ch.andre601.advancedserverlist.paper.objects.impl.PaperPlayerImpl;
import ch.andre601.advancedserverlist.paper.objects.impl.PaperServerImpl;
import com.viaversion.viaversion.api.Via;
import me.clip.placeholderapi.PlaceholderAPI;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
@@ -47,22 +43,19 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
public class PAPIPlaceholders<F> extends PlaceholderExpansion{
public class PAPIPlaceholders extends PlaceholderExpansion{
private final BukkitCore<F> plugin;
private final PaperCore plugin;
private PAPIPlaceholders(BukkitCore<F> plugin){
public PAPIPlaceholders(PaperCore plugin){
this.plugin = plugin;
this.register();
}
public static <F> PAPIPlaceholders<F> init(BukkitCore<F> plugin){
return new PAPIPlaceholders<>(plugin);
}
@Override
public @NotNull String getIdentifier(){
return "asl";
@@ -85,16 +78,15 @@ public class PAPIPlaceholders<F> extends PlaceholderExpansion{
@Override
public String onPlaceholderRequest(Player pl, @NotNull String identifier){
InetSocketAddress address = pl.getAddress();
String host = resolveVirtualHost(pl, address);
String host = pl.getVirtualHost() == null ? null : pl.getVirtualHost().getHostString();
CachedPlayer cached = plugin.getCore().getPlayerHandler().getCachedPlayer(pl.getUniqueId());
int protocol = resolveProtocol(pl);
int online = Bukkit.getOnlinePlayers().size();
int max = Bukkit.getMaxPlayers();
BukkitServer server = new BukkitServerImpl(plugin.getWorldCache().worlds(), online, max, host);
GenericPlayer player = new BukkitPlayerImpl(pl, cached, protocol);
BukkitServer server = new PaperServerImpl(plugin.getWorldCache().worlds(), online, max, host);
BukkitPlayer player = new PaperPlayerImpl(pl, cached, protocol);
ServerListProfile profile = ProfileManager.resolveProfile(plugin.getCore(), player, server);
if(profile == null)
@@ -114,56 +106,36 @@ public class PAPIPlaceholders<F> extends PlaceholderExpansion{
extraPlayers = entry.extraPlayersCount();
}
BukkitServer finalServer = new BukkitServerImpl(plugin.getWorldCache().worlds(), online, max, host);
BukkitServer finalServer = new PaperServerImpl(plugin.getWorldCache().worlds(), online, max, host);
return switch(identifier.toLowerCase(Locale.ROOT)){
case "motd" -> getOption(entry.motd(), pl, player, finalServer);
case "favicon" -> getOption(entry.favicon(), pl, player, finalServer);
case "playercount_hover" -> getOption(entry.players(), pl, player, finalServer);
case "playercount_text" -> getOption(entry.playerCountText(), pl, player, finalServer);
// TODO: Remove extra_players_max in future release
case "extra_players_max", "playercount_extraplayers" -> extraPlayers == null ? "null" : String.valueOf(extraPlayers);
case "playercount_extraplayers" -> extraPlayers == null ? "null" : String.valueOf(extraPlayers);
case "playercount_maxplayers" -> maxPlayers == null ? "null" : String.valueOf(maxPlayers);
case "server_playersmax" -> String.valueOf(max);
default -> null;
};
}
private String getOption(String str, Player pl, GenericPlayer player, GenericServer server){
private int resolveProtocol(Player player){
if(Bukkit.getPluginManager().isPluginEnabled("ViaVersion"))
return Via.getAPI().getPlayerVersion(player.getUniqueId());
// Since ViaVersion isn't installed is the player's protocol version the same as the server.
//noinspection deprecation
return Bukkit.getUnsafe().getProtocolVersion();
}
private String getOption(String str, Player pl, BukkitPlayer player, BukkitServer server){
return getOption(Collections.singletonList(str), pl, player, server);
}
private String getOption(List<String> list, Player pl, GenericPlayer player, GenericServer server){
private String getOption(List<String> list, Player pl, BukkitPlayer player, BukkitServer server){
return ComponentParser.list(list)
.modifyText(text -> PlaceholderAPI.setPlaceholders(pl, text))
.modifyText(text -> StringReplacer.replace(text, player, server))
.toString();
}
private int resolveProtocol(Player player){
if(Bukkit.getPluginManager().isPluginEnabled("ViaVersion"))
return Via.getAPI().getPlayerVersion(player.getUniqueId());
// Since Spigot version requires ProtocolLib can we use it here safely if the plugin instance is SpigotCore.
if(plugin instanceof SpigotCore)
return ProtocolLibrary.getProtocolManager().getProtocolVersion(player);
// getProtocolVersion is only in Paper, so this is only called when main class isn't SpigotCore.
// Also, ViaVersion is not present, so the player protocol *should* be the same as the server.
//noinspection deprecation
return Bukkit.getUnsafe().getProtocolVersion();
}
private String resolveVirtualHost(Player player, InetSocketAddress address){
try {
// Server is a Paper Server with Player#getVirtualHost()
Class.forName("com.destroystokyo.paper.network.NetworkClient");
return player.getVirtualHost() == null ? null : player.getVirtualHost().getHostString();
}catch(ClassNotFoundException ignored){}
if(address == null)
return null;
return ProtocolLibEvents.getHostAddresses().get(address.getHostString());
}
}
@@ -23,40 +23,32 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.objects.placeholders;
package ch.andre601.advancedserverlist.paper.objects.placeholders;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.bukkit.objects.BukkitPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.paper.objects.impl.PaperPlayerImpl;
public class BukkitPlayerPlaceholders extends PlaceholderProvider{
public class PaperPlayerPlaceholders extends PlaceholderProvider{
private BukkitPlayerPlaceholders(){
public PaperPlayerPlaceholders(){
super("player");
}
public static BukkitPlayerPlaceholders init(){
return new BukkitPlayerPlaceholders();
}
@Override
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
if(!(player instanceof BukkitPlayer bukkitPlayer))
if(!(player instanceof PaperPlayerImpl paperPlayer))
return null;
return switch(placeholder){
case "name" -> bukkitPlayer.getName();
case "protocol" -> String.valueOf(bukkitPlayer.getProtocol());
case "uuid" -> bukkitPlayer.getUUID().toString();
case "hasPlayedBefore" -> returnValue(bukkitPlayer, bukkitPlayer.hasPlayedBefore());
case "isBanned" -> returnValue(bukkitPlayer, bukkitPlayer.isBanned());
case "isWhitelisted" -> returnValue(bukkitPlayer, bukkitPlayer.isWhitelisted());
case "name" -> paperPlayer.getName();
case "protocol" -> String.valueOf(paperPlayer.getProtocol());
case "uuid" -> paperPlayer.getUUID().toString();
case "hasPlayedBefore" -> String.valueOf(paperPlayer.hasPlayedBefore());
case "isBanned" -> String.valueOf(paperPlayer.isBanned());
case "isWhitelisted" -> String.valueOf(paperPlayer.isWhitelisted());
default -> null;
};
}
private String returnValue(BukkitPlayer player, Object value){
return player.getPlayer() == null ? null : String.valueOf(value);
}
}
@@ -23,38 +23,38 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.objects.placeholders;
package ch.andre601.advancedserverlist.paper.objects.placeholders;
import ch.andre601.advancedserverlist.api.bukkit.objects.BukkitServer;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.paper.objects.impl.PaperServerImpl;
import org.bukkit.Bukkit;
import org.bukkit.World;
public class BukkitServerPlaceholders extends PlaceholderProvider{
public class PaperServerPlaceholders extends PlaceholderProvider{
private BukkitServerPlaceholders(){
public PaperServerPlaceholders(){
super("server");
}
public static BukkitServerPlaceholders init(){
return new BukkitServerPlaceholders();
}
@Override
public String parsePlaceholder(String placeholders, GenericPlayer player, GenericServer server){
if(!(server instanceof BukkitServer bukkitServer))
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
if(!(server instanceof PaperServerImpl paperServer))
return null;
String[] args = placeholders.split("\\s", 2);
String[] args = placeholder.split("\\s", 2);
return switch(args[0]){
case "playersOnline" -> {
if(args.length >= 2){
String[] worlds = args[1].split(",");
int players = 0;
for(int i = 1; i < args.length; i++){
World world = bukkitServer.getWorlds().get(args[i]);
for(String worldName : worlds){
if(worldName.isEmpty())
continue;
World world = paperServer.worlds().get(worldName);
if(world == null)
continue;
@@ -64,19 +64,19 @@ public class BukkitServerPlaceholders extends PlaceholderProvider{
yield String.valueOf(players);
}
yield String.valueOf(bukkitServer.getPlayersOnline());
yield String.valueOf(paperServer.playersOnline());
}
case "playersMax" -> {
if(args.length >= 2)
yield null;
yield String.valueOf(bukkitServer.getPlayersMax());
yield String.valueOf(paperServer.getPlayersMax());
}
case "host" -> {
if(args.length >= 2)
yield null;
yield bukkitServer.getHost();
yield paperServer.getHost();
}
case "whitelistEnabled" -> {
if(args.length >= 2)
@@ -1,24 +1,24 @@
#
# This file is kept for Folia support.
#
name: 'AdvancedServerList'
author: 'Andre_601'
version: '${plugin.version}'
description: '${plugin.description}'
main: 'ch.andre601.advancedserverlist.spigot.SpigotCore'
main: 'ch.andre601.advancedserverlist.paper.PaperCore'
api-version: 1.19
api-version: '1.19'
folia-supported: true
libraries:
- 'org.spongepowered:configurate-yaml:4.1.2'
- 'net.kyori:adventure-api:4.12.0'
- 'net.kyori:adventure-text-minimessage:4.12.0'
- 'net.kyori:adventure-text-serializer-legacy:4.12.0'
- 'net.kyori:adventure-platform-bukkit:4.2.0'
- 'com.squareup.okhttp3:okhttp:4.10.0'
softdepend:
- 'ProtocolLib'
- 'PlaceholderAPI'
- 'Maintenance'
+2 -2
View File
@@ -38,7 +38,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.commit/>
<plugin.version>3.5.1</plugin.version>
<plugin.version>3.6.0</plugin.version>
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
<api.version>v3.1.0</api.version>
@@ -57,7 +57,7 @@
<modules>
<module>core</module>
<module>bungeecord</module>
<module>bukkit</module>
<module>paper</module>
<module>velocity</module>
<module>version-uploader</module>
</modules>
+2 -2
View File
@@ -1,4 +1,4 @@
mkdocs-material==9.4.5
mkdocs-glightbox==0.3.4
mkdocs-material==9.4.14
mkdocs-glightbox==0.3.5
mkdocs-awesome-pages-plugin==2.9.2
git+https://github.com/Andre601/mkdocs-pagenav-generator
+1 -1
View File
@@ -84,7 +84,7 @@
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.11.0</version>
<version>4.12.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
@@ -51,10 +51,14 @@ public class VelocityServerPlaceholders 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++){
RegisteredServer registeredServer = proxy.getServers().get(args[i]);
int players = 0;
for(String serverName : servers){
if(serverName.isEmpty())
continue;
RegisteredServer registeredServer = proxy.getServers().get(serverName);
if(registeredServer == null)
continue;
+3 -3
View File
@@ -52,19 +52,19 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
<version>1.4.14</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2.1</version>
<version>5.2.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.11.0</version>
<version>4.12.0</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -29,10 +29,10 @@ import java.util.List;
public enum PlatformInfo{
BUKKIT(
"bukkit",
"bukkit/target/AdvancedServerList-Bukkit-{{version}}.jar",
"spigot", "paper", "folia"
PAPER(
"paper",
"paper/target/AdvancedServerList-Paper-{{version}}.jar",
"paper", "folia"
),
BUNGEECORD(
"bungeecord",
@@ -38,7 +38,6 @@ import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.mime.FileBody;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.entity.mime.StringBody;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpMessage;
@@ -79,8 +78,6 @@ public class HangarVersionUploader{
return CompletableFuture.completedFuture(null);
}
final Namespace project = new Namespace("Andre_601", "AdvancedServerList");
final String releaseVersion = release.tagName().startsWith("v") ? release.tagName().substring(1) : release.tagName();
final String pluginVersion = VersionUploader.retrieveVersion();
@@ -93,23 +90,23 @@ public class HangarVersionUploader{
boolean preRelease = release.prerelease();
final List<Path> filePaths = List.of(
new File(PlatformInfo.BUKKIT.getFilePath().replace("{{version}}", pluginVersion)).toPath(),
new File(PlatformInfo.PAPER.getFilePath().replace("{{version}}", pluginVersion)).toPath(),
new File(PlatformInfo.BUNGEECORD.getFilePath().replace("{{version}}", pluginVersion)).toPath(),
new File(PlatformInfo.VELOCITY.getFilePath().replace("{{version}}", pluginVersion)).toPath()
);
final List<Dependency> bukkitDependencies = List.of(
Dependency.fromNamespace("ViaVersion", false, new Namespace("ViaVersion", "ViaVersion")),
Dependency.fromNamespace("Maintenance", false, new Namespace("kennytv", "Maintenance")),
Dependency.fromNamespace("PlaceholderAPI", false, new Namespace("HelpChat", "PlaceholderAPI"))
final List<Dependency> paperDependencies = List.of(
Dependency.fromNamespace("ViaVersion", false),
Dependency.fromNamespace("Maintenance", false),
Dependency.fromNamespace("PlaceholderAPI", false)
);
final List<Dependency> bungeeDependencies = List.of(
Dependency.fromNamespace("PapiProxyBridge", false, new Namespace("William278", "PAPIProxyBridge")),
Dependency.fromNamespace("Maintenance", false, new Namespace("kennytv", "Maintenance"))
Dependency.fromNamespace("PapiProxyBridge", false),
Dependency.fromNamespace("Maintenance", false)
);
final List<Dependency> velocityDependencies = List.of(
Dependency.fromNamespace("PapiProxyBridge", false, new Namespace("William278", "PAPIProxyBridge")),
Dependency.fromNamespace("Maintenance", false, new Namespace("kennytv", "Maintenance"))
Dependency.fromNamespace("PapiProxyBridge", false),
Dependency.fromNamespace("Maintenance", false)
);
final List<MultipartObject> fileInfo = List.of(
@@ -121,7 +118,7 @@ public class HangarVersionUploader{
final Version versionUpload = new Version(
releaseVersion,
Map.of(
Platform.PAPER, bukkitDependencies,
Platform.PAPER, paperDependencies,
Platform.WATERFALL, bungeeDependencies,
Platform.VELOCITY, velocityDependencies
),
@@ -138,21 +135,22 @@ public class HangarVersionUploader{
if(dryrun){
String json = GSON.toJson(versionUpload);
LOGGER.info("Namespace: {}", project);
LOGGER.info("Namespace: AdvancedServerList");
LOGGER.info("JSON: {}", json);
return CompletableFuture.completedFuture(json);
}
try(CloseableHttpClient client = HttpClients.createDefault()){
return uploadVersion(client, project, versionUpload, filePaths);
try{
HttpClient client = HttpClients.createDefault();
return uploadVersion(client, versionUpload, filePaths);
}catch(ParseException | IOException ex){
LOGGER.warn("Unable to upload to Hangar! Encountered an exception.", ex);
return CompletableFuture.failedFuture(ex);
LOGGER.warn("Encountered an exception while uploading to Hangar!", ex);
return CompletableFuture.completedFuture(ex);
}
}
private CompletableFuture<?> uploadVersion(HttpClient client, Namespace namespace, Version versionUpload, List<Path> filePaths) throws IOException, ParseException{
private CompletableFuture<?> uploadVersion(HttpClient client, Version versionUpload, List<Path> filePaths) throws IOException, ParseException{
return CompletableFuture.supplyAsync(() -> {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addPart("versionUpload", new StringBody(GSON.toJson(versionUpload), ContentType.APPLICATION_JSON));
@@ -161,7 +159,7 @@ public class HangarVersionUploader{
builder.addPart("files", new FileBody(path.toFile(), ContentType.DEFAULT_BINARY));
}
HttpPost post = new HttpPost(API_URL + "projects/" + namespace + "/upload");
HttpPost post = new HttpPost(API_URL + "projects/AdvancedServerList/upload");
post.setEntity(builder.build());
try{
this.addAuthHeader(client, post);
@@ -25,18 +25,18 @@
package ch.andre601.advancedserverlist.versionuploader.hangar.version;
public record Dependency(String name, boolean required, Namespace namespace, String externalUrl){
public record Dependency(String name, String externalUrl, boolean required){
public Dependency{
if(namespace == null && externalUrl == null)
if(name == null && externalUrl == null)
throw new IllegalStateException("Either a namespace or external URL needs to be defined.");
}
public static Dependency fromNamespace(String name, boolean required, Namespace namespace){
return new Dependency(name, required, namespace, null);
public static Dependency fromNamespace(String name, boolean required){
return new Dependency(name, null, required);
}
public static Dependency fromUrl(String name, boolean required, String url){
return new Dependency(name, required, null, url);
public static Dependency fromUrl(String url, boolean required){
return new Dependency(null, url, required);
}
}
@@ -47,7 +47,7 @@ public class ModrinthVersionUploader{
private static final Logger LOGGER = LoggerFactory.getLogger(ModrinthVersionUploader.class);
private final List<PlatformInfo> platforms = List.of(
PlatformInfo.BUKKIT,
PlatformInfo.PAPER,
PlatformInfo.BUNGEECORD,
PlatformInfo.VELOCITY
);
@@ -87,7 +87,9 @@ public class ModrinthVersionUploader{
List<ProjectVersion.ProjectDependency> dependencies = new ArrayList<>();
// Maintenance plugin
dependencies.add(new ProjectVersion.ProjectDependency(null, "VCAqN1ln", null, ProjectVersion.ProjectDependencyType.OPTIONAL));
if(!platforms.get(i).getPlatform().equalsIgnoreCase("bukkit")){
// ViaVersion plugin
dependencies.add(new ProjectVersion.ProjectDependency(null, "P1OZGk5p", null, ProjectVersion.ProjectDependencyType.OPTIONAL));
if(!platforms.get(i).getPlatform().equalsIgnoreCase("paper")){
// PAPIProxyBridge plugin
dependencies.add(new ProjectVersion.ProjectDependency(null, "bEIUEGTX", null, ProjectVersion.ProjectDependencyType.OPTIONAL));
}