mirror of
https://codeberg.org/Andre601/AdvancedServerList.git
synced 2026-11-05 17:02:34 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c36667116 | ||
|
|
3417d7c0be | ||
|
|
96fa871204 | ||
|
|
aaacd9944f | ||
|
|
af44324cf1 | ||
|
|
77b6897bd4 | ||
|
|
9d963199ae | ||
|
|
580b87ebb5 | ||
|
|
efd5762162 | ||
|
|
62261ae6ed | ||
|
|
e52bfdf60b | ||
|
|
0152ba3e1a | ||
|
|
090787e292 | ||
|
|
25d14eeaae | ||
|
|
386d490596 | ||
|
|
207ce12452 | ||
|
|
b87703c36c | ||
|
|
41677d0635 | ||
|
|
dfdb2aa767 | ||
|
|
d14c5f80e8 | ||
|
|
bd9e376d08 | ||
|
|
578242078b | ||
|
|
f84842729d | ||
|
|
1daeecbbcf | ||
|
|
5dcab6c37c | ||
|
|
a146a10d53 | ||
|
|
75db0d5e96 | ||
|
|
644dd401d4 | ||
|
|
32d85c6be1 | ||
|
|
1b47af6714 | ||
|
|
4544696a54 | ||
|
|
a84848daee | ||
|
|
3f8dd90e28 | ||
|
|
f633741988 | ||
|
|
7e9ea9f470 | ||
|
|
c2c00dc47f | ||
|
|
027503efab | ||
|
|
7dd78cbbfc | ||
|
|
b27b8e78bd | ||
|
|
ad5b07feda | ||
|
|
d79784d1c0 | ||
|
|
ef84e85426 | ||
|
|
35782809ac | ||
|
|
3e3c4903e4 | ||
|
|
79b45fb29d | ||
|
|
46f40294e2 | ||
|
|
ca5ab5d221 | ||
|
|
b2e5d7ae28 | ||
|
|
649e9f07ef | ||
|
|
eaa86aa93b | ||
|
|
8a90619810 | ||
|
|
351db260ce | ||
|
|
bcc9d88e8c | ||
|
|
9c849157d3 | ||
|
|
f171c951e7 | ||
|
|
cae808e3fc | ||
|
|
ae8e6304f9 | ||
|
|
c975ba79b3 | ||
|
|
83fb13e1f2 | ||
|
|
586351e277 | ||
|
|
098b6be0f4 | ||
|
|
1c881d2832 | ||
|
|
e6f3d122c7 | ||
|
|
759474b344 | ||
|
|
6aef4c2de9 | ||
|
|
64d7c81c58 | ||
|
|
a070708323 | ||
|
|
e9ba86508c | ||
|
|
c1e3638534 | ||
|
|
f5260f3be1 | ||
|
|
51372aa8f4 | ||
|
|
025c9f4423 | ||
|
|
99c34dd343 | ||
|
|
cd91b799d6 | ||
|
|
5b7eb014a3 | ||
|
|
ad32952b97 | ||
|
|
4a1e552d5d | ||
|
|
ea1394dce9 | ||
|
|
317fa631e9 | ||
|
|
5dd26f6ab8 | ||
|
|
ba82df45ef | ||
|
|
d76339188d | ||
|
|
a9fb8f3ed6 | ||
|
|
18291a6865 | ||
|
|
83a1808ebc | ||
|
|
197967dea9 | ||
|
|
b25b65faba | ||
|
|
fafcd3ae18 | ||
|
|
daae88074f | ||
|
|
fbe019214d | ||
|
|
3e380342a7 | ||
|
|
fd2dbd2edb | ||
|
|
e969208ae9 | ||
|
|
77aa404e06 | ||
|
|
a6c1840858 | ||
|
|
762bd1d0fd | ||
|
|
02ce580433 | ||
|
|
c7b7feb476 | ||
|
|
0e145def83 | ||
|
|
03e32feb1d | ||
|
|
dbab282901 | ||
|
|
bd6b599267 | ||
|
|
1a63430c1e | ||
|
|
661f9e6ad4 | ||
|
|
6bd8d40ff4 | ||
|
|
16b74433ff | ||
|
|
1aaafe474f | ||
|
|
26a7697b0f | ||
|
|
ec6b653988 | ||
|
|
854eb67c54 | ||
|
|
00511f6e97 | ||
|
|
16eebb23a5 | ||
|
|
faae641c32 | ||
|
|
4fa542a242 | ||
|
|
2dc1f7ccc1 | ||
|
|
dd7b1a7392 | ||
|
|
a90d241cd2 | ||
|
|
452ac00ee7 | ||
|
|
f139270f0e | ||
|
|
b212b2af0f | ||
|
|
0d506379cf | ||
|
|
995793e66d | ||
|
|
f9ebc60d64 | ||
|
|
1d531a32e3 | ||
|
|
36340d9b9d | ||
|
|
d023e22934 | ||
|
|
260a0b4835 | ||
|
|
3f18aaaf5b | ||
|
|
3f0e7897d4 | ||
|
|
4bd35c810b | ||
|
|
b081be8f53 | ||
|
|
eb474d061b | ||
|
|
edbc893c65 | ||
|
|
d03dce9b29 |
No files matched your search
@@ -4,7 +4,7 @@ when:
|
||||
|
||||
steps:
|
||||
- name: "Build Jar and Upload"
|
||||
image: maven:3.9.9-eclipse-temurin-21
|
||||
image: maven:3.9.10-eclipse-temurin-21
|
||||
environment:
|
||||
CODEBERG_API_TOKEN:
|
||||
from_secret: cb_token
|
||||
|
||||
@@ -40,7 +40,7 @@ A Server List Profile is a single YAML file located in the plugin's `profiles` f
|
||||
Each file has a priority and optional condition. The priority is used to determine what file AdvancedServerList should use first - starting from highest number to lowest - with conditions being used to set when the profile should be used.
|
||||
Once a profile has been found with a condition returning true - which is the default should there be no condition - will AdvancedServerList use said profile.
|
||||
|
||||
> *Read more about [Priority](https://asl.andre601.ch/profiles/#priority) and [Conditions](https://asl.andre601.ch/profiles/#condition)*
|
||||
> *Read more about [Priority](https://asl.andre601.ch/profiles/options/priority) and [Conditions](https://asl.andre601.ch/profiles/options/condition)*
|
||||
|
||||
### Placeholders
|
||||
|
||||
@@ -92,6 +92,12 @@ English Video by KasaiSora
|
||||
Spanish Video by Ajneb97
|
||||
[](https://youtube.com/watch?v=rIbljm_4HVI)
|
||||
|
||||
Indonesian Video by faajrikha
|
||||
[](https://www.youtube.com/watch?v=-p938rOmqy4)
|
||||
|
||||
German Video by Finni Gamer
|
||||
[](https://www.youtube.com/watch?v=1Kh3cPMDd0c)
|
||||
|
||||
</p>
|
||||
</details>
|
||||
|
||||
|
||||
@@ -65,14 +65,14 @@
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.20-R0.2</version>
|
||||
<version>1.21-R0.3</version>
|
||||
<type>jar</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.20-R0.2</version>
|
||||
<version>1.21-R0.3</version>
|
||||
<type>javadoc</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
@@ -99,13 +99,13 @@
|
||||
<dependency>
|
||||
<groupId>space.arim.libertybans</groupId>
|
||||
<artifactId>bans-api</artifactId>
|
||||
<version>1.1.0-SNAPSHOT</version>
|
||||
<version>1.1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitlab.ruany</groupId>
|
||||
<artifactId>LiteBansAPI</artifactId>
|
||||
<version>0.5.0</version>
|
||||
<version>0.6.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+5
-5
@@ -74,14 +74,14 @@
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.21-R0.1-SNAPSHOT</version>
|
||||
<version>1.21-R0.3</version>
|
||||
<type>jar</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.21-R0.1-SNAPSHOT</version>
|
||||
<version>1.21-R0.3</version>
|
||||
<type>javadoc</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
@@ -126,19 +126,19 @@
|
||||
<dependency>
|
||||
<groupId>com.github.LeonMangler</groupId>
|
||||
<artifactId>PremiumVanishAPI</artifactId>
|
||||
<version>2.9.0-4</version>
|
||||
<version>2.9.18-2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.sayandev</groupId>
|
||||
<artifactId>sayanvanish-api</artifactId>
|
||||
<version>1.6.4</version>
|
||||
<version>1.6.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.sayandev</groupId>
|
||||
<artifactId>sayanvanish-proxy-bungeecord</artifactId>
|
||||
<version>1.6.4</version>
|
||||
<version>1.6.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
+16
-7
@@ -43,7 +43,7 @@
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<plugin.config.version>8</plugin.config.version>
|
||||
<plugin.config.version>9</plugin.config.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
@@ -93,7 +93,7 @@
|
||||
<dependency>
|
||||
<groupId>org.spongepowered</groupId>
|
||||
<artifactId>configurate-hocon</artifactId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.2.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.13.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -133,9 +133,11 @@
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>33.4.0-jre</version>
|
||||
<version>33.4.8-jre</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Command Framework -->
|
||||
<dependency>
|
||||
<groupId>org.incendo</groupId>
|
||||
<artifactId>cloud-annotations</artifactId>
|
||||
@@ -155,11 +157,18 @@
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- Annotations -->
|
||||
<dependency>
|
||||
<groupId>org.jspecify</groupId>
|
||||
<artifactId>jspecify</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Plugins -->
|
||||
<dependency>
|
||||
<groupId>net.william278</groupId>
|
||||
<artifactId>papiproxybridge</artifactId>
|
||||
<version>1.7.2</version>
|
||||
<version>1.8.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -179,7 +188,7 @@
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.11.4</version>
|
||||
<version>5.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -206,7 +215,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.13.0</version>
|
||||
<version>3.14.0</version>
|
||||
<configuration>
|
||||
<compilerArgs>
|
||||
<arg>-parameters</arg>
|
||||
|
||||
@@ -52,6 +52,7 @@ import org.incendo.cloud.suggestion.SuggestionProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
@@ -196,6 +197,8 @@ public class AdvancedServerList<F>{
|
||||
getPlugin().getPluginLogger().info("<#3b90ff> / ____ \\ \\ ____) | | |_|____");
|
||||
getPlugin().getPluginLogger().info("<#3b90ff>/_/_/ \\_\\_\\_____/_/|______|_|");
|
||||
getPlugin().getPluginLogger().info("");
|
||||
|
||||
seasonalText();
|
||||
}
|
||||
|
||||
private void resolveVersion(){
|
||||
@@ -252,7 +255,8 @@ public class AdvancedServerList<F>{
|
||||
.permission(
|
||||
Permission.anyOf(
|
||||
Permission.permission("advancedserverlist.admin"),
|
||||
Permission.permission("advancedserverlist.command.profiles")
|
||||
Permission.permission("advancedserverlist.command.profiles"),
|
||||
Permission.permission("advancedserverlist.command.profiles.set")
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -283,4 +287,44 @@ public class AdvancedServerList<F>{
|
||||
default -> Description.of("The Value to use for this option. Leave empty to reset.");
|
||||
};
|
||||
}
|
||||
|
||||
// Adding some seasonal messages
|
||||
private void seasonalText(){
|
||||
LocalDate date = LocalDate.now();
|
||||
|
||||
switch(date.getMonth()){
|
||||
case JANUARY -> {
|
||||
if(date.getDayOfMonth() == 1){
|
||||
getPlugin().getPluginLogger().info("Happy new Year!");
|
||||
getPlugin().getPluginLogger().info("");
|
||||
}
|
||||
}
|
||||
case JUNE -> {
|
||||
getPlugin().getPluginLogger().info("Happy Pride Month!");
|
||||
getPlugin().getPluginLogger().info("");
|
||||
}
|
||||
case AUGUST -> {
|
||||
if(date.getDayOfMonth() == 1){
|
||||
getPlugin().getPluginLogger().info("Happy Birthday Switzerland!");
|
||||
getPlugin().getPluginLogger().info("");
|
||||
}
|
||||
}
|
||||
case OCTOBER -> {
|
||||
if(date.getDayOfMonth() == 31){
|
||||
getPlugin().getPluginLogger().info("Happy Halloween!");
|
||||
getPlugin().getPluginLogger().info("");
|
||||
}
|
||||
}
|
||||
case DECEMBER -> {
|
||||
if(date.getDayOfMonth() == 13){
|
||||
getPlugin().getPluginLogger().info("Happy Birthday Andre_601!");
|
||||
getPlugin().getPluginLogger().info("");
|
||||
}else
|
||||
if(date.getDayOfMonth() > 23 && date.getDayOfMonth() < 27){
|
||||
getPlugin().getPluginLogger().info("Merry Christmas!");
|
||||
getPlugin().getPluginLogger().info("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
-21
@@ -46,13 +46,13 @@ import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.help.result.CommandEntry;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.minecraft.extras.MinecraftHelp;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
import org.spongepowered.configurate.yaml.NodeStyle;
|
||||
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -424,14 +424,20 @@ public class CommandHandler{
|
||||
}
|
||||
|
||||
private static String getOptionValue(Object obj){
|
||||
return switch(obj){
|
||||
case null -> "";
|
||||
case Boolean bool -> Boolean.toString(bool);
|
||||
case Integer integer -> Integer.toString(integer);
|
||||
case String str -> str;
|
||||
default -> obj.toString();
|
||||
};
|
||||
|
||||
if(obj == null){
|
||||
return "";
|
||||
}else
|
||||
if(obj instanceof Boolean bool){
|
||||
return Boolean.toString(bool);
|
||||
}else
|
||||
if(obj instanceof Integer integer){
|
||||
return Integer.toString(integer);
|
||||
}else
|
||||
if(obj instanceof String str){
|
||||
return str;
|
||||
}else{
|
||||
return obj.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private final CommandManager<CmdSender> commandManager;
|
||||
@@ -507,7 +513,7 @@ public class CommandHandler{
|
||||
public void migrate(
|
||||
CmdSender sender,
|
||||
AdvancedServerList<?> core,
|
||||
@Nonnull @Argument(description = "The plugin to migrate from.") Plugin plugin
|
||||
@NonNull @Argument(description = "The plugin to migrate from.") Plugin plugin
|
||||
){
|
||||
if(plugin == Plugin.SERVERLISTPLUS){
|
||||
if(!core.getPlugin().isPluginEnabled("ServerListPlus")){
|
||||
@@ -546,7 +552,7 @@ public class CommandHandler{
|
||||
|
||||
@Command("profiles list")
|
||||
@CommandDescription("Lists all available profiles with their priority, conditions and if they are valid.")
|
||||
@Permission({"advancedserverlist.admin", "advancedserverlist.command.profiles"})
|
||||
@Permission({"advancedserverlist.admin", "advancedserverlist.command.profiles", "advancedserverlist.command.profiles.list"})
|
||||
@CommandType(CommandType.Type.ALL)
|
||||
public void list(CmdSender sender, AdvancedServerList<?> core){
|
||||
sender.sendMsg();
|
||||
@@ -585,12 +591,12 @@ public class CommandHandler{
|
||||
|
||||
@Command("profiles info <profile>")
|
||||
@CommandDescription("Provides info about a profile.")
|
||||
@Permission({"advancedserverlist.admin", "advancedserverlist.command.profiles"})
|
||||
@Permission({"advancedserverlist.admin", "advancedserverlist.command.profiles", "advancedserverlist.command.profiles.info"})
|
||||
@CommandType(CommandType.Type.PLAYER_ONLY)
|
||||
public void info(
|
||||
CmdSender sender,
|
||||
AdvancedServerList<?> core,
|
||||
@Nonnull @Argument(description = "Name of the profile to view.", suggestions = "profiles") String profile
|
||||
@NonNull @Argument(description = "Name of the profile to view.", suggestions = "profiles") String profile
|
||||
){
|
||||
if(!sender.isPlayer()){
|
||||
sender.sendErrorMsg("<red>This command can only be executed by Players!");
|
||||
@@ -723,12 +729,12 @@ public class CommandHandler{
|
||||
|
||||
@Command("profiles add <name>")
|
||||
@CommandDescription("Creates a new profile with default values applied.")
|
||||
@Permission({"advancedserverlist.admin", "advancedserverlist.command.profiles"})
|
||||
@Permission({"advancedserverlist.admin", "advancedserverlist.command.profiles", "advancedserverlist.command.profiles.add"})
|
||||
@CommandType(CommandType.Type.ALL)
|
||||
public void add(
|
||||
CmdSender sender,
|
||||
AdvancedServerList<?> core,
|
||||
@Nonnull @Argument(description = "Name of the profile to create.") String name
|
||||
@NonNull @Argument(description = "Name of the profile to create.") String name
|
||||
){
|
||||
if(name.isEmpty()){
|
||||
sender.sendErrorMsg("<red>Insufficient arguments.");
|
||||
@@ -754,13 +760,13 @@ public class CommandHandler{
|
||||
|
||||
@Command("profiles copy <profile> <name>")
|
||||
@CommandDescription("Creates a copy of an existing profile.")
|
||||
@Permission({"advancedserverlist.admin", "advancedserverlist.command.profiles"})
|
||||
@Permission({"advancedserverlist.admin", "advancedserverlist.command.profiles", "advancedserverlist.command.profiles.copy"})
|
||||
@CommandType(CommandType.Type.ALL)
|
||||
public void copy(
|
||||
CmdSender sender,
|
||||
AdvancedServerList<?> core,
|
||||
@Nonnull @Argument(description = "Name of the profile to copy.", suggestions = "profiles") String profile,
|
||||
@Nonnull @Argument(description = "Name of the copy.") String name
|
||||
@NonNull @Argument(description = "Name of the profile to copy.", suggestions = "profiles") String profile,
|
||||
@NonNull @Argument(description = "Name of the copy.") String name
|
||||
){
|
||||
if(profile.isEmpty() || name.isEmpty()){
|
||||
sender.sendErrorMsg("<red>Insufficient arguments.");
|
||||
@@ -912,12 +918,12 @@ public class CommandHandler{
|
||||
<grey>Max Players: %s<reset>
|
||||
<grey>Online Players: %s""".formatted(
|
||||
entry.motd() == null || entry.motd().isEmpty() ?
|
||||
"<i><white>None</white></i>" : String.join("\n", entry.motd()),
|
||||
"<i><white>None</white></i>" : String.join("<reset>\n", entry.motd()),
|
||||
entry.favicon() == null || entry.favicon().isEmpty() ?
|
||||
"<i><white>None</white></i>" : entry.favicon(),
|
||||
entry.hidePlayersEnabled().getOrDefault(false) ? "<green>Enabled</green>" : "<red>Disabled</red>",
|
||||
entry.hidePlayersHoverEnabled().getOrDefault(false) ? "<green>Enabled</green>" : "<red>Disabled</red>",
|
||||
entry.players().isEmpty() ? "<i><white>None</white></i>" : String.join("\n", entry.players()),
|
||||
entry.players().isEmpty() ? "<i><white>None</white></i>" : String.join("<reset>\n", entry.players()),
|
||||
entry.playerCountText() == null || entry.playerCountText().isEmpty() ?
|
||||
"<i><white>None</white></i>" : entry.playerCountText(),
|
||||
entry.extraPlayersEnabled().getOrDefault(false) ? entry.extraPlayersCount() : "<red>Disabled</red>",
|
||||
|
||||
@@ -190,9 +190,12 @@ public class PingEventHandler{
|
||||
if(ProfileManager.checkOption(entry.favicon()) && ignoreMaintenance(event, "favicon")){
|
||||
logger.debug(PingEventHandler.class, "'favicon' option set. Resolving '%s'...", entry.favicon());
|
||||
|
||||
String faviconString = StringReplacer.replace(entry.favicon(), player, server);
|
||||
String faviconString = StringReplacer.modifier(entry.favicon())
|
||||
.modify(text -> StringReplacer.replace(text, player, server))
|
||||
.modify(text -> event.parsePAPIPlaceholders(text, player))
|
||||
.asString();
|
||||
|
||||
F favicon = plugin.getFaviconHandler().getFavicon(faviconString);
|
||||
F favicon = plugin.getFaviconHandler().favicon(faviconString);
|
||||
|
||||
if(favicon == null){
|
||||
logger.debugWarn(PingEventHandler.class, "Favicon was invalid or not yet resolved! Using default favicon of Server/Proxy...");
|
||||
|
||||
@@ -46,7 +46,8 @@ public class ConfigMigrator{
|
||||
public static ConfigurationTransformation.Versioned create(){
|
||||
return ConfigurationTransformation.versionedBuilder()
|
||||
.versionKey("configVersion")
|
||||
.addVersion(LATEST, sevenToEight())
|
||||
.addVersion(LATEST, eightToNine())
|
||||
.addVersion(8, sevenToEight())
|
||||
.addVersion(7, sixToSeven())
|
||||
.addVersion(6, fiveToSix())
|
||||
.addVersion(5, fourToFive())
|
||||
@@ -56,6 +57,16 @@ public class ConfigMigrator{
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ConfigurationTransformation eightToNine(){
|
||||
return ConfigurationTransformation.builder()
|
||||
.addAction(NodePath.path(), (path, value) -> {
|
||||
value.node("faviconStrategy").set("resize");
|
||||
|
||||
return null;
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ConfigurationTransformation sevenToEight(){
|
||||
return ConfigurationTransformation.builder()
|
||||
.addAction(NodePath.path("disableDuringMaintenance"), (path, value) -> {
|
||||
|
||||
+207
-107
@@ -1,28 +1,3 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.handlers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
@@ -42,9 +17,12 @@ import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class FaviconHandler<F>{
|
||||
@@ -54,183 +32,305 @@ public class FaviconHandler<F>{
|
||||
private final ThreadPoolExecutor faviconThreadPool;
|
||||
private final Cache<String, CompletableFuture<F>> faviconCache;
|
||||
|
||||
private final Map<String, F> localFavicons = new HashMap<>();
|
||||
private final HttpClient client = HttpClient.newHttpClient();
|
||||
private final Random random = new Random();
|
||||
private final HttpClient client = HttpClient.newHttpClient();
|
||||
private final Map<String, FaviconPair<F>> localFavicons = new HashMap<>();
|
||||
|
||||
public FaviconHandler(AdvancedServerList<F> core){
|
||||
this.core = core;
|
||||
this.logger = core.getPlugin().getPluginLogger();
|
||||
this.faviconThreadPool = createFaviconThreadPool();
|
||||
this.faviconThreadPool = createThreadPool();
|
||||
this.faviconCache = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(core.getFileHandler().getLong(1, 1, "faviconCacheTime"), TimeUnit.MINUTES)
|
||||
.build();
|
||||
.expireAfterWrite(core.getFileHandler().getLong(1, 1, "faviconCacheTime"), TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
loadLocalFavicons();
|
||||
}
|
||||
|
||||
public F getFavicon(String input){
|
||||
if(localFavicons.size() > 0){
|
||||
logger.debug(FaviconHandler.class, "Current Local Favicons:");
|
||||
for(String key : localFavicons.keySet()){
|
||||
logger.debug(FaviconHandler.class, " - %s", key);
|
||||
}
|
||||
public F favicon(String input){
|
||||
if(localFavicons.containsKey(input.toLowerCase(Locale.ROOT))){
|
||||
logger.debug(FaviconHandler.class, "Returning local Favicon '%s'.", input);
|
||||
|
||||
return localFavicons.get(input.toLowerCase(Locale.ROOT)).favicon();
|
||||
}
|
||||
|
||||
if(input.equalsIgnoreCase("random")){
|
||||
logger.debug(FaviconHandler.class, "Input matches 'random'. Returning random Favicon...");
|
||||
return getRandomized();
|
||||
logger.debug(FaviconHandler.class, "Returning random local Favicon.");
|
||||
|
||||
FaviconPair<F> pair = randomFavicon();
|
||||
if(pair == null){
|
||||
logger.warn("Cannot return random Favicon. Make sure PNGs are available in the Favicons folder!");
|
||||
return null;
|
||||
}
|
||||
|
||||
return pair.favicon();
|
||||
}
|
||||
|
||||
if(localFavicons.containsKey(input.toLowerCase(Locale.ROOT))){
|
||||
logger.debug(FaviconHandler.class, "Input matches local favicon Image. Returning it...");
|
||||
return localFavicons.get(input.toLowerCase(Locale.ROOT));
|
||||
CompletableFuture<F> favicon = faviconCache.getIfPresent(input);
|
||||
if(favicon != null)
|
||||
return favicon.getNow(null);
|
||||
|
||||
logger.debug(FaviconHandler.class, "Processing '%s'", input);
|
||||
if(input.contains(";")){
|
||||
String[] parts = input.split(";");
|
||||
logger.debug(FaviconHandler.class, "Handling multi-part Favicon: ['%s']", String.join("', '", parts));
|
||||
favicon = CompletableFuture.supplyAsync(() -> {
|
||||
List<BufferedImage> images = new ArrayList<>();
|
||||
Arrays.stream(parts).forEach(part -> {
|
||||
logger.debug(FaviconHandler.class, "Creating BufferedImage for part '%s'...", part);
|
||||
images.add(create(part));
|
||||
});
|
||||
|
||||
if(images.isEmpty()){
|
||||
logger.debugWarn(FaviconHandler.class, "Unable to create Multi-part Favicon. List was empty.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return composeFavicon(images);
|
||||
}, faviconThreadPool);
|
||||
}else{
|
||||
logger.debug(FaviconHandler.class, "Handling Favicon input '%s'...", input);
|
||||
|
||||
favicon = CompletableFuture.supplyAsync(() -> {
|
||||
logger.debug(FaviconHandler.class, "Creating BufferedImage for '%s'...", input);
|
||||
|
||||
BufferedImage image = create(input);
|
||||
if(image == null){
|
||||
logger.warn("Cannot create Favicon for '%s'. BufferedImage was null!", input);
|
||||
return null;
|
||||
}
|
||||
|
||||
return createFavicon(image);
|
||||
}, faviconThreadPool);
|
||||
}
|
||||
|
||||
try{
|
||||
logger.debug(FaviconHandler.class, "Getting Favicon image from cache...");
|
||||
return faviconCache.get(input, () -> getFuture(input)).getNow(null);
|
||||
}catch(ExecutionException ex){
|
||||
logger.warn("Received ExecutionException while retrieving Favicon for '<white>%s</white>'.", ex, input);
|
||||
return null;
|
||||
}
|
||||
faviconCache.put(input, favicon);
|
||||
return favicon.getNow(null);
|
||||
}
|
||||
|
||||
public void cleanCache(){
|
||||
faviconCache.invalidateAll();
|
||||
localFavicons.clear();
|
||||
loadLocalFavicons();
|
||||
}
|
||||
|
||||
private CompletableFuture<F> getFuture(String input){
|
||||
private F composeFavicon(List<BufferedImage> images){
|
||||
logger.debug(FaviconHandler.class, "Composing Favicon out of %d part(s)...", images.size());
|
||||
BufferedImage image = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D graphics = image.createGraphics();
|
||||
|
||||
String strategy = core.getFileHandler().getString("resize", "faviconStrategy");
|
||||
int layer = 0;
|
||||
for(BufferedImage img : images){
|
||||
layer++;
|
||||
logger.debug(FaviconHandler.class, "Applying layer %d...", layer);
|
||||
if(img == null){
|
||||
logger.debugWarn(FaviconHandler.class, "Layer %d was null! Skipping...", layer);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(strategy.toLowerCase(Locale.ROOT)){
|
||||
case "center" -> {
|
||||
int height = img.getHeight();
|
||||
int width = img.getWidth();
|
||||
|
||||
int posHeight = 0;
|
||||
int posWidth = 0;
|
||||
if(height != 64){
|
||||
posHeight = (64 - height) / 2;
|
||||
}
|
||||
|
||||
// 64 - 128 = -64
|
||||
|
||||
if(width != 64){
|
||||
posWidth = (64 - width) / 2;
|
||||
}
|
||||
|
||||
graphics.drawImage(img, posWidth, posHeight, img.getWidth(), img.getHeight(), null);
|
||||
}
|
||||
case "none" -> graphics.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), null);
|
||||
default -> graphics.drawImage(img, 0, 0, 64, 64, null);
|
||||
}
|
||||
|
||||
logger.debug(FaviconHandler.class, "Applied layer %d!", layer);
|
||||
}
|
||||
|
||||
graphics.dispose();
|
||||
|
||||
logger.debug(FaviconHandler.class, "Image Composing complete! Creating Favicon instance...");
|
||||
return createFavicon(image);
|
||||
}
|
||||
|
||||
private BufferedImage create(String input){
|
||||
if(input.toLowerCase(Locale.ROOT).startsWith("https://")){
|
||||
logger.debug(FaviconHandler.class, "Resolving URL '%s'...", input);
|
||||
return CompletableFuture.supplyAsync(() -> fromURL(core, input), this.faviconThreadPool);
|
||||
logger.debug(FaviconHandler.class, "Handling URL '%s'...", input);
|
||||
return fromURL(input);
|
||||
}else
|
||||
if(input.equalsIgnoreCase("random")){
|
||||
return CompletableFuture.completedFuture(getRandomized());
|
||||
logger.debug(FaviconHandler.class, "Returning random local Favicon...");
|
||||
FaviconPair<F> pair = randomFavicon();
|
||||
return pair == null ? null : pair.image();
|
||||
}else
|
||||
if(input.toLowerCase(Locale.ROOT).endsWith(".png")){
|
||||
logger.debug(FaviconHandler.class, "Resolving image file '%s'...", input);
|
||||
return CompletableFuture.completedFuture(localFavicons.get(input.toLowerCase(Locale.ROOT)));
|
||||
logger.debug(FaviconHandler.class, "Returning local Favicon '%s'...", input);
|
||||
return localFavicons.get(input.toLowerCase(Locale.ROOT)).image();
|
||||
}else{
|
||||
logger.debug(FaviconHandler.class, "Resolving Name/UUID as https://mc-heads.net/avatar/%s/64...", input);
|
||||
return CompletableFuture.supplyAsync(() -> fromURL(core, "https://mc-heads.net/avatar/" + input + "/64"), this.faviconThreadPool);
|
||||
logger.debug(FaviconHandler.class, "Handling Player Name/UUID '%s'...", input);
|
||||
return fromURL("https://mc-heads.net/avatar/" + input + "/64");
|
||||
}
|
||||
}
|
||||
|
||||
private F getRandomized(){
|
||||
logger.debug(FaviconHandler.class, "Obtaining random Favicon...");
|
||||
private FaviconPair<F> randomFavicon(){
|
||||
if(localFavicons.isEmpty())
|
||||
return null;
|
||||
|
||||
List<F> faviconList = List.copyOf(localFavicons.values());
|
||||
List<FaviconPair<F>> favicons = new ArrayList<>(localFavicons.values());
|
||||
if(favicons.isEmpty())
|
||||
return null;
|
||||
|
||||
// Don't use Random for just one entry.
|
||||
if(faviconList.size() == 1)
|
||||
return faviconList.get(0);
|
||||
if(favicons.size() == 1)
|
||||
return favicons.getFirst();
|
||||
|
||||
synchronized(random){
|
||||
return faviconList.get(random.nextInt(faviconList.size()));
|
||||
return favicons.get(random.nextInt(favicons.size()));
|
||||
}
|
||||
}
|
||||
|
||||
private void loadLocalFavicons(){
|
||||
this.localFavicons.clear();
|
||||
|
||||
logger.info("[-] Loading local image files as Favicons...");
|
||||
logger.info("[-] Loading local images as Favicons...");
|
||||
|
||||
Path folder = core.getPlugin().getFolderPath().resolve("favicons");
|
||||
if(!Files.exists(folder)){
|
||||
try{
|
||||
Files.createDirectories(folder);
|
||||
logger.debugSuccess(FaviconHandler.class, "Created favicons folder.");
|
||||
logger.debugSuccess(FaviconHandler.class, "Created favicons folder");
|
||||
}catch(IOException ex){
|
||||
logger.failure("Cannot create favicons folder. Encountered an IOException.", ex);
|
||||
logger.warn("Encountered IOException while creating favicons folder.", ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try(Stream<Path> pathStream = Files.list(folder)){
|
||||
pathStream.filter(Files::isRegularFile)
|
||||
.filter(file -> file.getFileName().toString().endsWith(".png"))
|
||||
.forEach(this::loadFile);
|
||||
try(Stream<Path> stream = Files.list(folder)){
|
||||
stream.filter(Files::isRegularFile)
|
||||
.filter(file -> file.getFileName().toString().endsWith(".png"))
|
||||
.forEach(this::loadFile);
|
||||
|
||||
logger.success("Loaded <white>%d</white> local Favicons.", localFavicons.size());
|
||||
logger.success("Loaded <white>%s</white> local Favicon(s).", localFavicons.size());
|
||||
}catch(IOException ex){
|
||||
logger.failure("Cannot load files from favicons folder.", ex);
|
||||
logger.warn("Encountered IOException while loading local favicons.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadFile(Path path){
|
||||
try(InputStream stream = Files.newInputStream(path)){
|
||||
F favicon = createFavicon(stream);
|
||||
if(favicon == null){
|
||||
logger.failure("Cannot create Favicon from file '<white>%s</white>'. Received Favicon was null.", path.getFileName().toString());
|
||||
BufferedImage image = createBufferedImage(stream);
|
||||
if(image == null)
|
||||
return;
|
||||
}
|
||||
|
||||
localFavicons.put(path.getFileName().toString().toLowerCase(Locale.ROOT), favicon);
|
||||
logger.debugSuccess(FaviconHandler.class, "Loaded file '<white>%s</white>' as Favicon.", path.getFileName().toString());
|
||||
F favicon = core.getPlugin().createFavicon(image);
|
||||
if(favicon == null)
|
||||
return;
|
||||
|
||||
localFavicons.put(path.getFileName().toString().toLowerCase(Locale.ROOT), new FaviconPair<>(image, favicon));
|
||||
}catch(IOException ex){
|
||||
logger.failure("Cannot create Favicon from file '<white>%s</white>'. Encountered IOException.", ex);
|
||||
logger.warn("Encountered IOException while creating a Favicon from '%s'.", ex, path.getFileName().toString());
|
||||
}catch(Exception ex){
|
||||
logger.warn("Encountered an Exceotion while creating a Favicon from '%s'.", ex, path.getFileName().toString());
|
||||
}
|
||||
}
|
||||
|
||||
private F fromURL(AdvancedServerList<F> core, String url){
|
||||
private BufferedImage fromURL(String url){
|
||||
try{
|
||||
logger.debug(FaviconHandler.class, "Creating Request for URL '%s'...", url);
|
||||
logger.debug(FaviconHandler.class, "Creating request for URL '%s'...", url);
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(new URI(url))
|
||||
.header("User-Agent", "AdvancedServerList-" + core.getPlugin().getLoader() + "/" + core.getVersion())
|
||||
.build();
|
||||
.uri(new URI(url))
|
||||
.header("User-Agent", "AdvancedServerList-" + core.getPlugin().getLoader() + "/" + core.getVersion())
|
||||
.build();
|
||||
|
||||
try(InputStream stream = client.send(request, HttpResponse.BodyHandlers.ofInputStream()).body()){
|
||||
return createFavicon(stream);
|
||||
}catch(InterruptedException | IOException ex){
|
||||
logger.warn("Cannot create Favicon from URL '<white>%s</white>'. Encountered an Exception.", ex, url);
|
||||
return createBufferedImage(stream);
|
||||
}catch(IOException ex){
|
||||
logger.warn("Encountered IOException while performing a web request for '%s'.", ex, url);
|
||||
return null;
|
||||
}catch(InterruptedException ex){
|
||||
logger.warn("Encountered an InterruptedException while performing a web request for '%s'.", ex, url);
|
||||
return null;
|
||||
}
|
||||
}catch(URISyntaxException ex){
|
||||
logger.warn("Cannot create Favicon from URL '<white>%s</white>'. Encountered a URISyntaxException.", ex, url);
|
||||
logger.warn("Received URISyntaxException for URL '%s'", ex, url);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private F createFavicon(InputStream stream){
|
||||
private BufferedImage createBufferedImage(InputStream stream){
|
||||
logger.debug(FaviconHandler.class, "Creating BufferedImage from InputStream...");
|
||||
try{
|
||||
logger.debug(FaviconHandler.class, "Creating BufferedImage from InputStream...");
|
||||
BufferedImage original = ImageIO.read(stream);
|
||||
if(original == null){
|
||||
logger.warn("Cannot create Favicon. Received null BufferedImage.");
|
||||
logger.warn("Cannot create Favicon. Received a null BufferedImage!");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Don't waste resources resizing images already having right size.
|
||||
if(original.getWidth() == 64 && original.getHeight() == 64){
|
||||
logger.debug(FaviconHandler.class, "BufferedImage is 64x64 pixels. No resizing needed.");
|
||||
return core.getPlugin().createFavicon(original);
|
||||
logger.debug(FaviconHandler.class, "Check image size for possible resizing...");
|
||||
if(original.getHeight() == 64 && original.getWidth() == 64){
|
||||
logger.debug(FaviconHandler.class, "Image is 64x64. No resizing needed!");
|
||||
return original;
|
||||
}
|
||||
|
||||
logger.debug(FaviconHandler.class, "Resizing image to 64x64 pixels...");
|
||||
logger.debug(FaviconHandler.class, "Applying Favicon resize strategy...");
|
||||
BufferedImage image = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D graphics2D = image.createGraphics();
|
||||
Graphics2D graphics = image.createGraphics();
|
||||
|
||||
graphics2D.drawImage(original, 0, 0, 64, 64, null);
|
||||
graphics2D.dispose();
|
||||
String resizeMode = core.getFileHandler().getString("resize", "faviconStrategy");
|
||||
switch(resizeMode.toLowerCase(Locale.ROOT)){
|
||||
case "center" -> {
|
||||
int height = original.getHeight();
|
||||
int width = original.getWidth();
|
||||
|
||||
int posHeight = 0;
|
||||
int posWidth = 0;
|
||||
if(height != 64){
|
||||
posHeight = (64 - height) / 2;
|
||||
}
|
||||
|
||||
if(width != 64){
|
||||
posWidth = (64 - width) / 2;
|
||||
}
|
||||
|
||||
graphics.drawImage(original, posWidth, posHeight, original.getWidth(), original.getHeight(), null);
|
||||
}
|
||||
case "none" -> graphics.drawImage(original, 0, 0, original.getWidth(), original.getHeight(), null);
|
||||
default -> graphics.drawImage(original, 0, 0, 64, 64, null);
|
||||
}
|
||||
|
||||
logger.debug(FaviconHandler.class, "Image resized! Returning Favicon...");
|
||||
return core.getPlugin().createFavicon(image);
|
||||
}catch(Exception ex){
|
||||
logger.warn("Unable to create Favicon. Received Exception.", ex);
|
||||
graphics.dispose();
|
||||
|
||||
logger.debug(FaviconHandler.class, "Image resized. Returning it...");
|
||||
return image;
|
||||
}catch(IOException ex){
|
||||
logger.warn("Encountered an IOException while processing Favicon!", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private ThreadPoolExecutor createFaviconThreadPool(){
|
||||
private F createFavicon(BufferedImage image){
|
||||
try{
|
||||
return core.getPlugin().createFavicon(image);
|
||||
}catch(Exception ex){
|
||||
logger.warn("Encountered an Exception while trying to create a Favicon instance.", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private ThreadPoolExecutor createThreadPool(){
|
||||
return new ThreadPoolExecutor(3, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1024), r -> {
|
||||
Thread t = new Thread(r, "AdvancedServerList-FaviconThread");
|
||||
t.setDaemon(true);
|
||||
|
||||
return t;
|
||||
});
|
||||
}
|
||||
|
||||
private record FaviconPair<F>(BufferedImage image, F favicon){}
|
||||
}
|
||||
+6
-13
@@ -120,20 +120,13 @@ public class ProfileManager{
|
||||
}
|
||||
|
||||
public static boolean checkOption(Object obj){
|
||||
if(obj == null)
|
||||
return false;
|
||||
return switch(obj){
|
||||
case List<?> list -> !list.isEmpty(); // Check if list isn't empty
|
||||
case String str -> !str.isEmpty(); // Check if String is not empty
|
||||
case NullBool nb -> nb.getOrDefault(false); // Return NullBool's value
|
||||
case null, default -> false;
|
||||
};
|
||||
|
||||
if(obj instanceof List<?> list){
|
||||
return !list.isEmpty(); // Check if list isn't empty
|
||||
}else
|
||||
if(obj instanceof String str){
|
||||
return !str.isEmpty(); // Check if String is not empty
|
||||
}else
|
||||
if(obj instanceof NullBool nb){
|
||||
return nb.getOrDefault(false); // Return NullBool's value
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static <T> T resolve(ProfileEntry defProfile, ProfileEntry profile, Function<ProfileEntry, T> function){
|
||||
|
||||
+23
@@ -34,9 +34,14 @@ import ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.toke
|
||||
import ch.andre601.expressionparser.ParseWarnCollector;
|
||||
|
||||
import java.text.ParsePosition;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class StringReplacer{
|
||||
|
||||
public static StringModifier modifier(String text){
|
||||
return new StringModifier(text);
|
||||
}
|
||||
|
||||
public static String replace(String input, GenericPlayer player, GenericServer server){
|
||||
if(input == null)
|
||||
return null;
|
||||
@@ -148,4 +153,22 @@ public class StringReplacer{
|
||||
|
||||
return replacement;
|
||||
}
|
||||
|
||||
public static class StringModifier{
|
||||
private String value;
|
||||
|
||||
public StringModifier(String value){
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public StringModifier modify(Function<String, String> function){
|
||||
this.value = function.apply(value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public String asString(){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,19 @@ printBanner: true
|
||||
#
|
||||
faviconCacheTime: 1
|
||||
|
||||
#
|
||||
# Sets how AdvancedServerList should handle the size and positioning of images for favicons.
|
||||
#
|
||||
# Available options:
|
||||
#
|
||||
# - resize: Resizes the image to 64x64 pixels if it isn't these dimensions already.
|
||||
# - center: Doesn't resize the image, but instead tries to center it as good as possible in a 64x64 area.
|
||||
# - none: Doesn't resize the image and leaves it positioned at x 0 and y 0 (top-left) of the 64x64 area.
|
||||
#
|
||||
# Setting any not listed option or leaving this blank/removing it sets the option to resize.
|
||||
#
|
||||
faviconStrategy: 'resize'
|
||||
|
||||
#
|
||||
# Options to disable while the Maintenance Plugin is present and Maintenance Mode is active.
|
||||
#
|
||||
|
||||
@@ -10,9 +10,9 @@ priority: 0
|
||||
# Set condition(s) that should return true to display this profile.
|
||||
# This allows you to create profiles to only show for specific scenarios (i.e. player is banned).
|
||||
#
|
||||
# Multiple conditions can be chaing with the keywords 'and', 'or', or their counterparts '&&' and '||'.
|
||||
# 'AND'/'&&' and 'OR'/'||' can be used to chain together multiple conditions.
|
||||
#
|
||||
# No condition or an empty condition will be treated as true by default.
|
||||
# Removing the condition option or setting it to an empty String will be treated as a true condition being returned.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#condition
|
||||
#
|
||||
@@ -40,8 +40,11 @@ profiles:
|
||||
|
||||
#
|
||||
# Set the "Message of the day" to display.
|
||||
# This option supports RGB colors for 1.16+ Servers and clients, including gradients using MiniMessage's <gradient>
|
||||
# option.
|
||||
# This option supports RGB colors for 1.16+ Servers and clients. More advanced MiniMessage features such as <gradient>
|
||||
# can be used for further styling the text.
|
||||
#
|
||||
# <center> can be put at the start of a line to have AdvancedServerList automatically center the text as good as
|
||||
# possible.
|
||||
#
|
||||
# Only the first two lines will be considered and any additional one is ignored.
|
||||
#
|
||||
@@ -55,27 +58,30 @@ motd:
|
||||
|
||||
#
|
||||
# Set the Favicon (image on the left of a server entry) to display.
|
||||
# This option supports three types of inputs:
|
||||
# This option supports three types of input:
|
||||
#
|
||||
# 1. Name, including .png extension, pointing to an image located in the plugin's favicons folder.
|
||||
# 2. "random" to display a random PNG from the favicons folder.
|
||||
# 1. Filename, including the .png extension, matching a filename in the favicons folder of the plugin.
|
||||
# - 'random' can be used to have AdvancedServerList select a random image from the favicons folder every time
|
||||
# the server is pinged.
|
||||
# 3. URL pointing to an image.
|
||||
# 4. Player name, UUID or placeholders returning one of these.
|
||||
# https://mc-heads.net will be used to retrieve an image of the provided name/UUID.
|
||||
# 4. Player name, UUID or a placeholder that returns either.
|
||||
# - https://mc-heads.net will be used to retrieve an image of the provided name/UUID.
|
||||
#
|
||||
# Note on favicons not showing:
|
||||
# AdvancedServerList has to create a Favicon object for the Proxy/Server to use which takes time to do so.
|
||||
# To not delay the Proxy/Server from being displayed (increase the loading time on the player end) is this creation
|
||||
# done asynchronously for URL/Player name/UUID. This has the downside that the Proxy/Server may be done handling the
|
||||
# ping before the Favicon is created, causing none to be displayed.
|
||||
# Note that this won't happen with local favicons, as those are created during the plugin's startup.
|
||||
#
|
||||
# Any images above or below 64x64 pixels will be automatically resized to these dimensions.
|
||||
# Any image below or above 64x64 pixels will be resized according to the faviconResizeMode option in the config.yml.
|
||||
#
|
||||
# If not present or empty (favicon: ''), defaults to not modifying the favicon.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#favicon
|
||||
#
|
||||
# "The favicon isn't showing!"
|
||||
# This is a side effect of using either URLs or player names/UUIDs for the favicon.
|
||||
# These types require AdvancedServerList to create a new favicon object from scratch. This action takes a significant
|
||||
# amount of time, which can cause the server to show with a huge ping.
|
||||
# To avoid this is this action performed asynchronously. This means that the plugin doesn't wait for the favicon to
|
||||
# be created before continuing, which can result in no favicon being available when it is done handling the ping.
|
||||
# This should only happen for the first ping of a player and subsequent pings should display the favicon, if the
|
||||
# pings are done within the configured cache time (See 'faviconCacheTime' in the config.yml).
|
||||
#
|
||||
favicon: ''
|
||||
|
||||
#
|
||||
@@ -106,7 +112,7 @@ playerCount:
|
||||
#
|
||||
# Set the lines shown when the player hovers over the player count.
|
||||
# Unlike the MOTD option does this one only support basic color and formatting codes. Any RGB colors will be
|
||||
# downsampled to the nearest matching color.
|
||||
# down-sampled to the nearest matching color.
|
||||
#
|
||||
# If not present or empty (hover: []), defaults to not modifying the hover.
|
||||
#
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import re
|
||||
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
from mkdocs.structure.files import Files
|
||||
from mkdocs.structure.pages import Page
|
||||
from re import Match
|
||||
|
||||
def on_page_markdown(
|
||||
markdown: str, *, page: Page, config: MkDocsConfig, files: Files
|
||||
):
|
||||
def replace(match: Match):
|
||||
platform = match.group(1)
|
||||
if platform == "paper": return "[:fontawesome-solid-paper-plane:](https://papermc.io){ .md-button .md-button--icon title=\"PaperMC\" target=\"_blank\" rel=\"noopener\" }"
|
||||
elif platform == "bungee": return "[:simple-spigotmc:](https://spigotmc.org){ .md-button .md-button--icon title=\"BungeeCord\" target=\"_blank\" rel=\"noopener\" }"
|
||||
elif platform == "velocity": return "[:simple-velocity:](https://velocitypowered.com){ .md-button .md-button--icon title=\"Velocity\" target=\"_blank\" rel=\"noopener\" }"
|
||||
elif platform == "proxies": return "[:simple-spigotmc:](https://spigotmc.org){ .md-button .md-button--icon title=\"BungeeCord\" target=\"_blank\" rel=\"noopener\" } [:simple-velocity:](https://velocitypowered.com){ .md-button .md-button--icon title=\"Velocity\" target=\"_blank\" rel=\"noopener\" }"
|
||||
elif platform == "all": return "[:fontawesome-solid-paper-plane:](https://papermc.io){ .md-button .md-button--icon title=\"PaperMC\" target=\"_blank\" rel=\"noopener\" } [:simple-spigotmc:](https://spigotmc.org){ .md-button .md-button--icon title=\"BungeeCord\" target=\"_blank\" rel=\"noopener\" } [:simple-velocity:](https://velocitypowered.com){ .md-button .md-button--icon title=\"Velocity\" target=\"_blank\" rel=\"noopener\" }"
|
||||
else: return platform
|
||||
|
||||
return re.sub(
|
||||
r"<!-- icon:(paper|bungee|velocity|proxies|all) -->",
|
||||
replace, markdown, flags = re.I | re.M
|
||||
)
|
||||
@@ -19,11 +19,11 @@
|
||||
{% endif %}
|
||||
|
||||
{% if enum.description %}
|
||||
<p class="api-detail__description">
|
||||
<div class="api-detail__description" markdown>
|
||||
|
||||
{{ enum.description }}
|
||||
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block announce %}
|
||||
<span class="twemoji">{% include ".icons/material/party-popper.svg" %}</span>
|
||||
Celebrating <a href="https://andre601.ch/blog/2024/12-13-history-of-asl/" target="_blank" rel="nofollow"><b>25,000 downloads!</b></a> Thank you!
|
||||
<span class="twemoji">{% include ".icons/material/party-popper.svg" %}</span>
|
||||
<span class="twemoji">{% include ".icons/octicons/paintbrush-24.svg" %}</span>
|
||||
The <a href="/profiles">Profiles page</a> received a huge restructuring!
|
||||
{% endblock %}
|
||||
@@ -16,8 +16,7 @@ The BanPlugins Addon is available in downloads of AdvancedServerList on [:simple
|
||||
|
||||
**Supported Platforms:**
|
||||
|
||||
- :fontawesome-solid-paper-plane: Paper
|
||||
- :simple-spigotmc: BungeeCord
|
||||
<!-- icon:paper --> <!-- icon:bungee -->
|
||||
|
||||
| Placeholder | Description |
|
||||
|---------------------------------|------------------------------------------------------------------------------------------|
|
||||
@@ -57,9 +56,7 @@ motd:
|
||||
|
||||
**Supported Platforms:**
|
||||
|
||||
- :fontawesome-solid-paper-plane: Paper
|
||||
- :simple-spigotmc: BungeeCord
|
||||
- :fontawesome-solid-paper-plane: Velocity
|
||||
<!-- icon:all -->
|
||||
|
||||
| Placeholder | Description |
|
||||
|---------------------------------|------------------------------------------------------------------------------------------|
|
||||
@@ -95,9 +92,7 @@ motd:
|
||||
|
||||
**Supported Platforms:**
|
||||
|
||||
- :fontawesome-solid-paper-plane: Paper
|
||||
- :simple-spigotmc: BungeeCord
|
||||
- :fontawesome-solid-paper-plane: Velocity
|
||||
<!-- icon:all -->
|
||||
|
||||
| Placeholder | Description |
|
||||
|------------------------------|------------------------------------------------------------------------------------------|
|
||||
|
||||
+7
-3
@@ -18,11 +18,13 @@ The plugin [SayanVanish]{ target="_blank" rel="nofollow" } is hooking into Advan
|
||||
| `${sayanvanish online_here}` | Returns the number of online players on the same server that aren't vanished. |
|
||||
| `${sayanvanish online_total}` | Returns the number of online players on the entire network that aren't vanished.^[1](#n1)^ |
|
||||
| `${sayanvanish online_<server>}` | Returns the number of online players on `<server>` that aren't vanished.^[1](#n1)^ |
|
||||
| `${sayanvanish vanish_prefix}` | Returns the prefix for the player while they are vanished or an empty String. |
|
||||
| `${sayanvanish vanish_suffix}` | Returns the suffix for the player while they are vanished or an empty String. |
|
||||
|
||||
<small>^1^{ #n1 } Only works when Proxy mode is enabled and will otherwise return `PROXY_MODE IS NOT ENABLED!`</small>
|
||||
///
|
||||
|
||||
/// tab | :fontawesome-solid-paper-plane: Velocity
|
||||
/// tab | :simple-velocity: Velocity
|
||||
[:octicons-file-code-24: Source][source-velocity]
|
||||
|
||||
| Placeholder | Description |
|
||||
@@ -32,8 +34,10 @@ The plugin [SayanVanish]{ target="_blank" rel="nofollow" } is hooking into Advan
|
||||
| `${sayanvanish count}` | Returns the number of online players that are vanished. |
|
||||
| `${sayanvanish online_total}` | Returns the number of online players on the entire network that aren't vanished. |
|
||||
| `${sayanvanish online_<server>}` | Returns the number of online players on `<server>` that aren't vanished. |
|
||||
| `${sayanvanish vanish_prefix}` | Returns the prefix for the player while they are vanished or an empty String. |
|
||||
| `${sayanvanish vanish_suffix}` | Returns the suffix for the player while they are vanished or an empty String. |
|
||||
///
|
||||
|
||||
[SayanVanish]: https://modrinth.com/plugin/sayanvanish
|
||||
[source-paper]: https://github.com/Syrent/SayanVanish/blob/ffd740832fd914c6462c41917a91f575f43ee778/sayanvanish-bukkit/src/main/kotlin/org/sayandev/sayanvanish/bukkit/feature/features/hook/FeatureHookAdvancedServerList.kt
|
||||
[source-velocity]: https://github.com/Syrent/SayanVanish/blob/585279bf5480542858a9d3d91cfc4d844982aa0f/sayanvanish-proxy/sayanvanish-proxy-velocity/src/main/kotlin/org/sayandev/sayanvanish/velocity/feature/features/hook/FeatureHookAdvancedServerList.kt
|
||||
[source-paper]: https://github.com/Syrent/SayanVanish/blob/6e03b874464a7f07c0baba233c94cdfefab5d3e2/sayanvanish-bukkit/src/main/kotlin/org/sayandev/sayanvanish/bukkit/feature/features/hook/FeatureHookAdvancedServerList.kt
|
||||
[source-velocity]: https://github.com/Syrent/SayanVanish/blob/6e03b874464a7f07c0baba233c94cdfefab5d3e2/sayanvanish-proxy/sayanvanish-proxy-velocity/src/main/kotlin/org/sayandev/sayanvanish/velocity/feature/features/hook/FeatureHookAdvancedServerList.kt
|
||||
@@ -3,7 +3,7 @@ icon: octicons/plus-circle-24
|
||||
---
|
||||
|
||||
AdvancedServerList allows you to add your own Placeholders to be useable through its `${identifier value}` format.
|
||||
The benefit of this method over alternatives such as using PlaceholderAPI placeholders is availability and the fact that these placeholders can be used within the [`condition` option](../profiles/index.md#condition) of the plugin.
|
||||
The benefit of this method over alternatives such as using PlaceholderAPI placeholders is availability and the fact that these placeholders can be used within the [`condition` option](../profiles/options/condition.md) of the plugin.
|
||||
|
||||
Adding your own placeholder is relatively easy and only requires the main API module to be used in your dependencies, unless you need platform-specific values (Explained later on).
|
||||
|
||||
@@ -101,7 +101,7 @@ public class MyPlugin extends Plugin {
|
||||
```
|
||||
///
|
||||
|
||||
/// tab | :fontawesome-solid-paper-plane: Velocity Example
|
||||
/// tab | :simple-velocity: Velocity Example
|
||||
```java title="MyPlugin.java"
|
||||
@Plugin(
|
||||
id = "myplugin",
|
||||
|
||||
+5
-53
@@ -88,12 +88,10 @@ dependencies {
|
||||
|
||||
Dedicated pages to explain aspects of the API are available:
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
/// html | div.grid.cards
|
||||
- [:octicons-plus-circle-24: Adding Placeholders](adding-placeholders.md)
|
||||
- [:octicons-broadcast-24: Listening for Events](listening-for-events.md)
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
## Declare AdvancedServerList as (soft)depend
|
||||
|
||||
@@ -135,7 +133,7 @@ dependencies:
|
||||
////
|
||||
///
|
||||
|
||||
/// tab | :octicons-git-merge-24: BungeeCord
|
||||
/// tab | :simple-spigotmc: BungeeCord
|
||||
//// tab | Softdepend
|
||||
```yaml title="bungee.yml"
|
||||
name: "MyPlugin"
|
||||
@@ -163,7 +161,7 @@ depends:
|
||||
////
|
||||
///
|
||||
|
||||
/// tab | :octicons-git-merge-24: Velocity
|
||||
/// tab | :simple-velocity: Velocity
|
||||
//// tab | Softdepend (File)
|
||||
```json title="velocity-plugin.json"
|
||||
{
|
||||
@@ -251,50 +249,4 @@ public class MyPlugin {
|
||||
|
||||
### 4. You're done!
|
||||
|
||||
Your plugin should now hook into AdvancedServerList and register its own custom placeholders to use.
|
||||
|
||||
## Listening for events
|
||||
|
||||
<!-- admo:info These events require the platform-specific APIs -->
|
||||
|
||||
AdvancedServerList provides Events that your plugin can listen for specific situations.
|
||||
|
||||
### PreServerListSetEvent
|
||||
|
||||
This event is called **before** AdvancedServerList starts handling the PingEvent of the Server/Proxy.
|
||||
It allows you to get and alter the [ProfileEntry][profileentry] used in the PingEvent, or even outright cancel the event itself.
|
||||
|
||||
The event offers the following methods:
|
||||
|
||||
- [`getEntry()`][getentry] - Gets the currently set [`ProfileEntry`][profileentry].
|
||||
- [`setEntry(ProfileEntry)`][setentry] - Sets a new [`ProfileEntry`][profileentry] to use.
|
||||
- [`isCancelled()`][iscancelled] - Gets the current cancelled state of the event.
|
||||
- [`setCancelled(boolean)`][setcancelled] - Sets the current cancelled state.
|
||||
|
||||
Please check the server/proxy's documentation on how to listen for events with your plugin.
|
||||
|
||||
[getentry]: reference/api/ch.andre601.advancedserverlist.api/events/genericserverlistevent.md#getentry
|
||||
[setentry]: reference/api/ch.andre601.advancedserverlist.api/events/genericserverlistevent.md#setentry
|
||||
[iscancelled]: reference/api/ch.andre601.advancedserverlist.api/events/genericserverlistevent.md#iscancelled
|
||||
[setcancelled]: reference/api/ch.andre601.advancedserverlist.api/events/genericserverlistevent.md#setcancelled
|
||||
|
||||
### PostServerListSetEvent
|
||||
|
||||
This event is called **after** AdvancedServerList has completed its handling of the Server's/Proxy's PingEvent.
|
||||
|
||||
It provides a method to retrieve the [ProfileEntry][profileentry] used during the PingEvent.
|
||||
Do note that this ProfileEntry is **not** a representation of what is actually displayed in the server list, but rather what has been used by AdvancedServerList. It may also be `null` should the event handling get cancelled for any reason.
|
||||
|
||||
[profileentry]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/index.md
|
||||
|
||||
### ProfileEntry
|
||||
|
||||
The ProfileEntry record is the core class used within the `PreServerListSetEvent`. It sets what values (MOTD, Favicon, Players, etc.) should be displayed.
|
||||
Note that the record is - by nature - immutable and that the [`Builder`][builder] class should be used to create a new ProfileEntry instance to use.
|
||||
|
||||
A convenience method ([`builder()`][builder()]) exists to create a `Builder` instance from an existing `ProfileEntry` in case you only want to alter certain options while everything else should remain unchanged.
|
||||
|
||||
This allows you to customize the Server list using your plugin. Just keep in mind that other plugins may also do the same, overriding your changes.
|
||||
|
||||
[builder]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/builder.md
|
||||
[builder()]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/index.md#builder
|
||||
Your plugin should now hook into AdvancedServerList and register its own custom placeholders to use.
|
||||
@@ -7,12 +7,10 @@ These events are structurally the same across all platforms, yet still require t
|
||||
|
||||
The plugin currently offers the following events:
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
/// html | div.grid.cards
|
||||
- [PreServerListSetEvent](#preserverlistsetevent)
|
||||
- [PostServerListSetEvent](#postserverlistsetevent)
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
## PreServerListSetEvent
|
||||
|
||||
@@ -22,12 +20,16 @@ This event is executed before AdvancedServerList tries to modify the player list
|
||||
|
||||
The following methods are available to use:
|
||||
|
||||
| Method | Description |
|
||||
|--------------------------|--------------------------------------------------------------------------------|
|
||||
| `getEntry()` | Returns the [`ProfileEntry`][profileentry] that AdvancedServerList should use. |
|
||||
| `setEntry(ProfileEntry)` | Sets the [`ProfileEntry`][profileentry] that should be used. |
|
||||
| `isCancelled()` | Returns wether this event was cancelled or not. |
|
||||
| `setCancelled(boolean)` | Sets the event's cancelled state. |
|
||||
| Method | Description |
|
||||
|-----------------------------------------|--------------------------------------------------------------------------------|
|
||||
| [`getEntry()`][getentry] | Returns the [`ProfileEntry`][profileentry] that AdvancedServerList should use. |
|
||||
| [`setEntry(ProfileEntry)`][setentry] | Sets the [`ProfileEntry`][profileentry] that should be used. |
|
||||
| [`isCancelled()`][iscancelled] | Returns wether this event was cancelled or not. |
|
||||
| [`setCancelled(boolean)`][setcancelled] | Sets the event's cancelled state. |
|
||||
|
||||
[setentry]: reference/api/ch.andre601.advancedserverlist.api/events/genericserverlistevent.md#setentry
|
||||
[iscancelled]: reference/api/ch.andre601.advancedserverlist.api/events/genericserverlistevent.md#iscancelled
|
||||
[setcancelled]: reference/api/ch.andre601.advancedserverlist.api/events/genericserverlistevent.md#setcancelled
|
||||
|
||||
### Notes { #preserverlistsetevent-notes }
|
||||
|
||||
@@ -41,7 +43,9 @@ This event is executed after AdvancedServerList completed the server list modifi
|
||||
|
||||
| Method | Description |
|
||||
|--------------------------|--------------------------------------------------------------------------|
|
||||
| `getEntry()` | Returns the [`ProfileEntry`][profileentry] that AdvancedServerList used. |
|
||||
| [`getEntry()`][getentry] | Returns the [`ProfileEntry`][profileentry] that AdvancedServerList used. |
|
||||
|
||||
[getentry]: reference/api/ch.andre601.advancedserverlist.api/events/genericserverlistevent.md#getentry
|
||||
|
||||
### Notes { #postserverlistsetevent-notes }
|
||||
|
||||
@@ -50,7 +54,107 @@ This event is executed after AdvancedServerList completed the server list modifi
|
||||
|
||||
## Registering the Events
|
||||
|
||||
To register an event, please refer to our platforms documentation on how to do this.
|
||||
/// tab | :fontawesome-solid-paper-plane: Paper
|
||||
```java { title="MyPlugin.java" .annotate }
|
||||
public class MyPlugin extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// (1)
|
||||
Bukkit.getPluginManager().registerEvents(new ASLEventListener(), this);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. `getServer()` from the `JavaPlugin` class can be used here too instead of the `Bukkit` singleton.
|
||||
|
||||
```java { title="ASLEventListener.java" }
|
||||
public class ASLEventListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPreServerListSet(PreServerListSetEvent event) {
|
||||
System.out.println("PreServerListSetEvent fired!");
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPostServerListSetEvent(PostServerListSetEvent event) {
|
||||
System.out.println("PostServerListSetEvent fired!");
|
||||
}
|
||||
}
|
||||
```
|
||||
///
|
||||
|
||||
/// tab | :simple-spigotmc: BungeeCord
|
||||
```java { title="MyPlugin.java" }
|
||||
public class MyPlugin extends Plugin {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
getProxy().getPluginManager().registerListener(this, new ASLEventListener());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java { title="ASLEventListener.java" }
|
||||
public class ASLEventListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPreServerListSet(PreServerListSetEvent event) {
|
||||
System.out.println("PreServerListSetEvent fired!");
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPostServerListSetEvent(PostServerListSetEvent event) {
|
||||
System.out.println("PostServerListSetEvent fired!");
|
||||
}
|
||||
}
|
||||
```
|
||||
///
|
||||
|
||||
/// tab | :simple-velocity: Velocity
|
||||
```java { title="MyPlugin.java" }
|
||||
@Plugin(
|
||||
id = "myplugin",
|
||||
name = "MyPlugin",
|
||||
version = "1.0.0",
|
||||
authors = {"author"},
|
||||
dependencies = {
|
||||
@Dependency(
|
||||
id = "advancedserverlist",
|
||||
)
|
||||
}
|
||||
)
|
||||
public class MyPlugin {
|
||||
|
||||
private final ProxyServer proxy;
|
||||
|
||||
@Inject
|
||||
public MyPlugin(ProxyServer server) {
|
||||
this.proxy = proxy;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void init(ProxyInitializeEvent event) {
|
||||
proxy.getEventManager().register(this, new ASLEventListener());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java { title="ASLEventListener.java" }
|
||||
public class ASLEventListener {
|
||||
|
||||
@Subscribe
|
||||
public void onPreServerListSet(PreServerListSetEvent event) {
|
||||
System.out.println("PreServerListSetEvent fired!");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPostServerListSetEvent(PostServerListSetEvent event) {
|
||||
System.out.println("PostServerListSetEvent fired!");
|
||||
}
|
||||
}
|
||||
```
|
||||
///
|
||||
|
||||
## What is a ProfileEntry?
|
||||
|
||||
@@ -60,6 +164,7 @@ The `ProfileEntry` is a record, representing the values of a [Server List Profil
|
||||
It is important to note, that the `ProfileEntry` can be a representation of the [`profiles` option](../profiles/index.md#profiles), the global options or a mixture of both.
|
||||
If you want to create your own instance, you'll need to use the [`ProfileEntry.Builder` class](reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/builder.md) as the `ProfileEntry` is unmodifiable.
|
||||
|
||||
A convenience method in the form of `builder()` exists to create a Builder instance of the ProfileEntry with its values already pre-set.
|
||||
A convenience method in the form of [`builder()`][builder] exists to create a Builder instance of the ProfileEntry with its values already pre-set.
|
||||
|
||||
[profileentry]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/index.md
|
||||
[profileentry]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/index.md
|
||||
[builder]: reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/index.md#builder
|
||||
+2
@@ -3,9 +3,11 @@ api: true
|
||||
|
||||
constructors:
|
||||
- name: 'InvalidPlaceholderProviderException'
|
||||
description: Basic Constructor to create an instance of this Exception.
|
||||
parameters:
|
||||
- name: msg
|
||||
type: String
|
||||
description: The reason of the exception.
|
||||
---
|
||||
|
||||
# <api__class></api__class> InvalidPlaceholderProviderException
|
||||
|
||||
@@ -5,17 +5,15 @@ methods:
|
||||
- name: 'getName'
|
||||
description: |
|
||||
Returns the name of the player.
|
||||
Note that on Spigot, Paper and other forks can the name differ from the one cached by AdvancedServerList, if the plugin was able to retrieve an OfflinePlayer instance from the server. On BungeeCord and Velocity will the returned String always be the name from the cache.
|
||||
On BungeeCord and Velocity is the returned value always what AdvancedServerList has cached, while on paper the value may differ, should the plugin be able to obtain a OfflinePlayer instance from the Server.
|
||||
|
||||
Name may be whatever has been defined in AdvancedServerList's config.yml, should the player not be cached yet by the plugin.
|
||||
Name may also be whatever has been defined in AdvancedServerList's `unknownPlayer -> name` config.yml Option.
|
||||
returns: 'String representing the player''s name'
|
||||
type:
|
||||
name: String
|
||||
type: object
|
||||
- name: 'getProtocol'
|
||||
description: |
|
||||
Returns the protocol ID the player is using.
|
||||
The protocol ID is an integer used by Minecraft to determine what version a server or client is running.
|
||||
description: Returns the protocol ID the player is using. The protocol ID is a unique positive integer that is used in Minecraft to determine the Version used by the Client and Server.
|
||||
returns: 'Integer representing the protocol version of this player.'
|
||||
type:
|
||||
name: int
|
||||
@@ -23,7 +21,7 @@ methods:
|
||||
description: |
|
||||
Returns the unique ID associated with this player.
|
||||
|
||||
UUID may be whatever has been defined in AdvancedServerList's config.yml, should the player not be cached yet by AdvancedServerList.
|
||||
UUID may also be whatever has been defined in AdvancedServerList's `unknownPlayer -> uuid` config.yml Option.
|
||||
returns: 'UUID of the player'
|
||||
type:
|
||||
name: UUID
|
||||
@@ -32,10 +30,10 @@ methods:
|
||||
|
||||
# <api__interface></api__interface> GenericPlayer
|
||||
|
||||
A basic interface used to store generic player data to use in placeholder resolving.
|
||||
The different variants of AdvancedServerList implement this into their own class and may provide additional data not available through this interface.
|
||||
Interface used by the API to share common information across all platforms.
|
||||
|
||||
The following values will always be present, no matter the platform this interface is used on:
|
||||
Platform-specific interfaces extending this interface are available and may offer additional features in addition to what this interface is offering.
|
||||
This interface always offers data for the following:
|
||||
|
||||
- [Name of the Player](#getname)
|
||||
- [Protocol version of the Player](#getprotocol)
|
||||
|
||||
@@ -24,4 +24,11 @@ methods:
|
||||
|
||||
# <api__interface></api__interface> GenericServer
|
||||
|
||||
Simple class used to wrap around some generic server data such as online player count, number of total players that can join and the host (IP/Domain) that got pinged by the player.
|
||||
Interface used to share common information across all platforms.
|
||||
|
||||
Platform-specific interfaces extending this interface are available and may offer additional features in addition to what this interface is offering.
|
||||
This interface always offers data for the following:
|
||||
|
||||
- [Players currently online on the Proxy/Server](#getplayersonline)
|
||||
- [Max Players allowed to join the Proxy/Server](#getplayersmax)
|
||||
- [IP/Domain pinged by the Player](#gethost)
|
||||
@@ -48,4 +48,4 @@ methods:
|
||||
|
||||
# <api__enum></api__enum> NullBool
|
||||
|
||||
Enum used to return a `Boolean` value with a default one should no value be set.
|
||||
Enum used to return a [`Boolean`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Boolean.html){ target="_blank" rel="noopener" } Value with a fallback, should the boolean be `null`.
|
||||
@@ -14,7 +14,7 @@ constructors:
|
||||
methods:
|
||||
- name: 'parsePlaceholder'
|
||||
description: |
|
||||
Method called by AdvancedServerList's StringReplacer class to replace any appearances of `${<identifier> <placeholder> with whatever value a matching PlaceholderProvider may return.
|
||||
Method called by AdvancedServerList's StringReplacer class to replace any appearances of `${<identifier> <placeholder>}` with whatever value a matching PlaceholderProvider may return.
|
||||
|
||||
Returning `null` will be treated as an invalid placeholder by the plugin, making it return the placeholder as-is without any changes.
|
||||
parameters:
|
||||
|
||||
File renamed without changes.
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
@@ -1,7 +1,4 @@
|
||||
document$.subscribe(async () => {
|
||||
const url = 'https://api.allorigins.win/raw?url='
|
||||
const apiUrl = `https://api.allorigins.win/raw?url=${encodeURIComponent('https://codeberg.org/api/v1/repos/Andre601/asl-api/releases/latest')}`
|
||||
|
||||
const repo_stats = document.querySelector('[data-md-component="source"] .md-source__repository');
|
||||
|
||||
async function loadCodebergInfo(data) {
|
||||
@@ -61,7 +58,7 @@ document$.subscribe(async () => {
|
||||
}
|
||||
|
||||
async function fetchApiInfo() {
|
||||
const tag = await fetch(`${apiUrl}`)
|
||||
const tag = await fetch('https://codeberg.org/api/v1/repos/Andre601/asl-api/releases/latest')
|
||||
.then(_ => _.json());
|
||||
|
||||
const data = {
|
||||
@@ -74,8 +71,8 @@ document$.subscribe(async () => {
|
||||
|
||||
async function fetchInfo() {
|
||||
const [release, repo] = await Promise.all([
|
||||
fetch(`${url}${encodeURIComponent('https://codeberg.org/api/v1/repos/Andre601/AdvancedServerList/releases/latest')}`).then(_ => _.json()),
|
||||
fetch(`${url}${encodeURIComponent('https://codeberg.org/api/v1/repos/Andre601/AdvancedServerList')}`).then(_ => _.json()),
|
||||
fetch('https://codeberg.org/api/v1/repos/Andre601/AdvancedServerList/releases/latest').then(_ => _.json()),
|
||||
fetch('https://codeberg.org/api/v1/repos/Andre601/AdvancedServerList').then(_ => _.json()),
|
||||
]);
|
||||
|
||||
const data = {
|
||||
|
||||
@@ -55,4 +55,10 @@
|
||||
|
||||
.md-banner__inner.md-grid.md-typeset {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.md-typeset .md-button.md-button--icon {
|
||||
padding: .5em;
|
||||
line-height: 0;
|
||||
color: var(--md-default-fg-color);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
title: /asl clearcache
|
||||
---
|
||||
|
||||
# `/asl clearcache`
|
||||
|
||||
/// info |
|
||||
**Permissions:**
|
||||
|
||||
- `advancedserverlist.admin`
|
||||
- `advancedserverlist.command.clearcache`
|
||||
///
|
||||
|
||||
Resets the current Favicon and Player cache.
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: /asl help
|
||||
---
|
||||
|
||||
# `/asl help [query]`
|
||||
|
||||
/// info |
|
||||
**Permissions:**
|
||||
|
||||
- `advancedserverlist.admin`
|
||||
- `advancedserverlist.command.help`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `[query]` - Optional search query to use
|
||||
///
|
||||
|
||||
Displays information about provided commands.
|
||||
If no query is provided will it list all commands. A page number can be used as query to switch between pages.
|
||||
+3
-73
@@ -4,78 +4,8 @@ icon: octicons/rel-file-path-24
|
||||
|
||||
# Commands
|
||||
|
||||
The plugin adds commands to use for various things related to the plugin itself.
|
||||
The main command is `/advancedserverlist` but an alias called `/asl` is also registered to use.
|
||||
AdvancedServerList adds commands that can be accessed via `/advancedserverlist` or `/asl` and provide different functionalities.
|
||||
|
||||
## Permissions
|
||||
## Available commands
|
||||
|
||||
The main permission is `advancedserverlist.admin` for all commands, but you can also grant access to specific commands using `advancedserverlist.command.<subcommand>` instead (i.e. `advancedserverlist.command.help` to grant access to [`/asl help [query]`](#help)).
|
||||
|
||||
## Subcommands
|
||||
|
||||
The following subcommands are available (Subcommands are case-insensitive):
|
||||
|
||||
- [`help [query]`](#help)
|
||||
- [`reload`](#reload)
|
||||
- [`clearCache`](#clearcache)
|
||||
- [`migrate <plugin>`](#migrate)
|
||||
- [`profiles {add <name> | copy <profile> <name> | info <profile> | list | set <profile> <option> [value]}`](#profiles)
|
||||
|
||||
### `help [query]` { #help }
|
||||
|
||||
**Permission:** `advancedserverlist.command.help`
|
||||
**Arguments:**
|
||||
|
||||
- `[query]` - Optional search query to receive help info from.
|
||||
|
||||
Shows a list of all available [subcommands](#subcommands) for AdvancedServerList.
|
||||
|
||||
----
|
||||
|
||||
### `reload`
|
||||
|
||||
**Permission:** `advancedserverlist.command.reload`
|
||||
|
||||
Reloads the plugin's `config.yml` and all available YAML files in the `profiles` folder.
|
||||
|
||||
----
|
||||
|
||||
### `clearcache`
|
||||
|
||||
**Permission:** `advancedserverlist.command.clearcache`
|
||||
|
||||
Clears the currently cached favicons and players.
|
||||
|
||||
----
|
||||
|
||||
### `migrate <plugin>` { #migrate }
|
||||
|
||||
**Permission:** `advancedserverlist.command.migrate`
|
||||
**Arguments:**
|
||||
|
||||
- `<plugin>` - The plugin to migrate from.
|
||||
|
||||
Migrates files from one plugin over to AdvancedServerList.
|
||||
Check the [Migration Page](../migration/index.md) for a list of supported plugins.
|
||||
|
||||
----
|
||||
|
||||
### `profiles {add <profile> | copy <profile> <name> | info <profile> | list | set <profile> <option> [value]}` { #profiles }
|
||||
|
||||
**Permission:** `advancedserverlist.command.profiles`
|
||||
**Arguments:**
|
||||
|
||||
- `add <profile>` - Creates a new profile using the default profile values.
|
||||
- `<profile>` - Name of the profile to use.
|
||||
- `copy <profile> <name>` - Creates a copy of an existing profile.
|
||||
- `<profile>` - Name of the profile to copy from.
|
||||
- `<name>` - Name of the copy to have.
|
||||
- `info <profile>` - Returns information of a profile. Only executable by players.
|
||||
- `<profile>` - Name of the profile to fetch info from.
|
||||
- `list` - Lists all loaded profiles. The entries have hover text for extra info.
|
||||
- `set <profile> <option> [value]` - Edits values of a profile. Requires [`/asl reload`](#reload) to apply changes.
|
||||
- `<profile>` - Name of the profile to edit.
|
||||
- `<option>` - The option to edit.
|
||||
- `[value]` - The new value to set. Leave empty to reset to the default.
|
||||
|
||||
Creates, copies or shows profiles in AdvancedServerList.
|
||||
{nav}
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: /asl migrate
|
||||
---
|
||||
|
||||
# `/asl migrate <plugin>`
|
||||
|
||||
/// info |
|
||||
**Permissions:**
|
||||
|
||||
- `advancedserverlist.admin`
|
||||
- `advancedserverlist.command.`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `<plugin>` - The plugin to migrate from.
|
||||
///
|
||||
|
||||
Migrates configuration from the provided plugin to AdvancedServerList.
|
||||
A list of supported plugins and known limitations can be found on the [Migration page](../migration/index.md).
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
title: /asl profiles
|
||||
---
|
||||
|
||||
# `/asl profiles add <profile>`<br>`/asl profiles copy <profile> <name>`<br>`/asl profiles info <profile>`<br>`/asl profiles list`<br>`/asl profiles set <profile> <option> [value]`
|
||||
|
||||
/// info |
|
||||
**Permissions:**
|
||||
|
||||
- `advancedserverlist.admin`
|
||||
- `advancedserverlist.command.profiles`
|
||||
|
||||
**Subcommands:**
|
||||
|
||||
- [`add <profile>`](#add)
|
||||
- [`copy <profile> <name>`](#copy)
|
||||
- [`info <profile>`](#info)
|
||||
- [`list`](#list)
|
||||
- [`set <profile> <option> [value]`](#set)
|
||||
///
|
||||
|
||||
Creates, copies, lists (info of) or sets values for profiles.
|
||||
|
||||
## `/asl profiles add <profile>` { #add }
|
||||
|
||||
/// info |
|
||||
**Permissions:**
|
||||
|
||||
- `advancedserverlist.admin`
|
||||
- `advancedserverlist.command.profiles`
|
||||
- `advancedserverlist.command.profiles.add`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `<profile>` - Name of the profile to create.
|
||||
///
|
||||
|
||||
Creates a new profile using default values.
|
||||
[`/asl reload`](reload.md) needs to be executed to load the new profile.
|
||||
|
||||
## `/asl profiles copy <profile> <name>` { #copy }
|
||||
|
||||
/// info |
|
||||
**Permissions:**
|
||||
|
||||
- `advancedserverlist.admin`
|
||||
- `advancedserverlist.command.profiles`
|
||||
- `advancedserverlist.command.profiles.copy`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `<profile>` - Name of the profile to copy.
|
||||
- `<name>` - Name of the copy to make.
|
||||
///
|
||||
|
||||
Creates a copy from the provided profile.
|
||||
[`/asl reload`](reload.md) needs to be executed to load the new profile.
|
||||
|
||||
## `/asl profiles info <profile>` { #info }
|
||||
|
||||
/// info |
|
||||
**Permissions:**
|
||||
|
||||
- `advancedserverlist.admin`
|
||||
- `advancedserverlist.command.profiles`
|
||||
- `advancedserverlist.command.profiles.info`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `<profile>` - The profile to list info from.
|
||||
///
|
||||
|
||||
<!-- admo:info Only executable by players. -->
|
||||
|
||||
Lists currently set values for the provided profile.
|
||||
Each option has hover text to show the value and a click action to receive the matching [`/asl profiles set ...`](#set) command.
|
||||
|
||||
## `/asl profiles list` { #list }
|
||||
|
||||
/// info |
|
||||
**Permissions:**
|
||||
|
||||
- `advancedserverlist.admin`
|
||||
- `advancedserverlist.command.profiles`
|
||||
- `advancedserverlist.command.profiles.list`
|
||||
///
|
||||
|
||||
Lists all currently loaded profiles.
|
||||
Each profile has a hover text displaying their priority, condition and whether they are considered valid.
|
||||
|
||||
## `/asl profiles set <profile> <option> [value]` { #set }
|
||||
|
||||
/// info |
|
||||
**Permissions:**
|
||||
|
||||
- `advancedserverlist.admin`
|
||||
- `advancedserverlist.command.profiles`
|
||||
- `advancedserverlist.command.profiles.set`
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `<profile>` - The profile to modify.
|
||||
- `<option>` - The option to modify.
|
||||
- `[value]` - Optional value to set. Leave empty to reset the option.
|
||||
///
|
||||
|
||||
Sets the config option `<option>` to the provided `[value]`. Leaving value empty results in the option being reset to an empty/unset state.
|
||||
[`/asl reload`](reload.md) needs to be executed to apply the changes.
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
title: /asl reload
|
||||
---
|
||||
|
||||
# `/asl reload`
|
||||
|
||||
/// info |
|
||||
**Permissions:**
|
||||
|
||||
- `advancedserverlist.admin`
|
||||
- `advancedserverlist.command.reload`
|
||||
///
|
||||
|
||||
Reloads the config.yml and any YAML file in the profiles folder.
|
||||
@@ -12,8 +12,7 @@ The guide is designed to be as easy to understand as possible. If you still have
|
||||
The first step would be to download the plugin from a download page of your choice.
|
||||
AdvancedServerList is available on the following places (Please note the current status!):
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
/// html | div.grid.cards
|
||||
- [:simple-modrinth: **Modrinth**][modrinth]{ target="_blank" rel="nofollow" }
|
||||
|
||||
----
|
||||
@@ -38,8 +37,7 @@ AdvancedServerList is available on the following places (Please note the current
|
||||
----
|
||||
|
||||
:octicons-alert-24:{ style="color: var(--md-badge-fg--warning);" } **Discontinued!**
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
[spigot]: https://www.spigotmc.org/resources/102910/
|
||||
|
||||
@@ -47,8 +45,7 @@ The plugin is available for Paper, BungeeCord, Waterfall and Velocity, and has b
|
||||
|
||||
The plugin also supports these additional plugins. They are all optional.
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
/// html | div.grid.cards
|
||||
- [**PlaceholderAPI**][placeholderapi]{ target="_blank" rel="nofollow" }
|
||||
|
||||
----
|
||||
@@ -58,7 +55,7 @@ The plugin also supports these additional plugins. They are all optional.
|
||||
----
|
||||
|
||||
**Supported on:**
|
||||
:fontawesome-solid-paper-plane: Paper
|
||||
<!-- icon:paper -->
|
||||
|
||||
- [**ViaVersion**][viaversion]{ target="_blank" rel="nofollow" }
|
||||
|
||||
@@ -69,7 +66,7 @@ The plugin also supports these additional plugins. They are all optional.
|
||||
----
|
||||
|
||||
**Supported on:**
|
||||
:fontawesome-solid-paper-plane: Paper
|
||||
<!-- icon:paper -->
|
||||
|
||||
- [**PAPIProxyBridge**][papiproxybridge]{ target="_blank" rel="nofollow" }
|
||||
|
||||
@@ -80,7 +77,7 @@ The plugin also supports these additional plugins. They are all optional.
|
||||
----
|
||||
|
||||
**Supported on:**
|
||||
:simple-spigotmc: BungeeCord, :fontawesome-solid-paper-plane: Velocity
|
||||
<!-- icon:proxies -->
|
||||
|
||||
- [**Maintenance**][maintenance]{ target="_blank" rel="nofollow" }
|
||||
|
||||
@@ -91,7 +88,7 @@ The plugin also supports these additional plugins. They are all optional.
|
||||
----
|
||||
|
||||
**Supported on:**
|
||||
:fontawesome-solid-paper-plane: Paper, :simple-spigotmc: BungeeCord, :fontawesome-solid-paper-plane: Velocity
|
||||
<!-- icon:all -->
|
||||
|
||||
- [**BanPlugins Addon**][addon]
|
||||
|
||||
@@ -102,9 +99,8 @@ The plugin also supports these additional plugins. They are all optional.
|
||||
----
|
||||
|
||||
**Supported on:**
|
||||
:fontawesome-solid-paper-plane: Paper, :simple-spigotmc: BungeeCord, :fontawesome-solid-paper-plane: Velocity
|
||||
|
||||
</div>
|
||||
<!-- icon:all -->
|
||||
///
|
||||
|
||||
[addon]: ../addons/first-party/banplugins.md
|
||||
|
||||
@@ -136,7 +132,7 @@ 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).
|
||||
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/options/favicon.md).
|
||||
|
||||
#### Profiles folder and default.yml { #profiles-folder-and-default-yml }
|
||||
|
||||
@@ -159,9 +155,9 @@ priority: 0
|
||||
# Set condition(s) that should return true to display this profile.
|
||||
# This allows you to create profiles to only show for specific scenarios (i.e. player is banned).
|
||||
#
|
||||
# Multiple conditions can be chaing with the keywords 'and', 'or', or their counterparts '&&' and '||'.
|
||||
# 'AND'/'&&' and 'OR'/'||' can be used to chain together multiple conditions.
|
||||
#
|
||||
# No condition or an empty condition will be treated as true by default.
|
||||
# Removing the condition option or setting it to an empty String will be treated as a true condition being returned.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#condition
|
||||
#
|
||||
@@ -189,8 +185,11 @@ profiles:
|
||||
|
||||
#
|
||||
# Set the "Message of the day" to display.
|
||||
# This option supports RGB colors for 1.16+ Servers and clients, including gradients using MiniMessage's <gradient>
|
||||
# option.
|
||||
# This option supports RGB colors for 1.16+ Servers and clients. More advanced MiniMessage features such as <gradient>
|
||||
# can be used for further styling the text.
|
||||
#
|
||||
# <center> can be put at the start of a line to have AdvancedServerList automatically center the text as good as
|
||||
# possible.
|
||||
#
|
||||
# Only the first two lines will be considered and any additional one is ignored.
|
||||
#
|
||||
@@ -204,20 +203,14 @@ motd:
|
||||
|
||||
#
|
||||
# Set the Favicon (image on the left of a server entry) to display.
|
||||
# This option supports three types of inputs:
|
||||
# This option supports three types of input:
|
||||
#
|
||||
# 1. Name, including .png extension, pointing to an image located in the plugin's favicons folder.
|
||||
# 2. "random" to display a random PNG from the favicons folder.
|
||||
# 1. Filename, including the .png extension, matching a filename in the favicons folder of the plugin.
|
||||
# - 'random' can be used to have AdvancedServerList select a random image from the favicons folder every time
|
||||
# the server is pinged.
|
||||
# 3. URL pointing to an image.
|
||||
# 4. Player name, UUID or placeholders returning one of these.
|
||||
# https://mc-heads.net will be used to retrieve an image of the provided name/UUID.
|
||||
#
|
||||
# Note on favicons not showing:
|
||||
# AdvancedServerList has to create a Favicon object for the Proxy/Server to use which takes time to do so.
|
||||
# To not delay the Proxy/Server from being displayed (increase the loading time on the player end) is this creation
|
||||
# done asynchronously for URL/Player name/UUID. This has the downside that the Proxy/Server may be done handling the
|
||||
# ping before the Favicon is created, causing none to be displayed.
|
||||
# Note that this won't happen with local favicons, as those are created during the plugin's startup.
|
||||
# 4. Player name, UUID or a placeholder that returns either.
|
||||
# - https://mc-heads.net will be used to retrieve an image of the provided name/UUID.
|
||||
#
|
||||
# Any images above or below 64x64 pixels will be automatically resized to these dimensions.
|
||||
#
|
||||
@@ -225,6 +218,15 @@ motd:
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#favicon
|
||||
#
|
||||
# "The favicon isn't showing!"
|
||||
# This is a side effect of using either URLs or player names/UUIDs for the favicon.
|
||||
# These types require AdvancedServerList to create a new favicon object from scratch. This action takes a significant
|
||||
# amount of time, which can cause the server to show with a huge ping.
|
||||
# To avoid this is this action performed asynchronously. This means that the plugin doesn't wait for the favicon to
|
||||
# be created before continuing, which can result in no favicon being available when it is done handling the ping.
|
||||
# This should only happen for the first ping of a player and subsequent pings should display the favicon, if the
|
||||
# pings are done within the configured cache time (See 'faviconCacheTime' in the config.yml).
|
||||
#
|
||||
favicon: ''
|
||||
|
||||
#
|
||||
@@ -255,7 +257,7 @@ playerCount:
|
||||
#
|
||||
# Set the lines shown when the player hovers over the player count.
|
||||
# Unlike the MOTD option does this one only support basic color and formatting codes. Any RGB colors will be
|
||||
# downsampled to the nearest matching color.
|
||||
# down-sampled to the nearest matching color.
|
||||
#
|
||||
# If not present or empty (hover: []), defaults to not modifying the hover.
|
||||
#
|
||||
@@ -448,6 +450,19 @@ printBanner: true
|
||||
#
|
||||
faviconCacheTime: 1
|
||||
|
||||
#
|
||||
# Sets how AdvancedServerList should handle the size and positioning of images for favicons.
|
||||
#
|
||||
# Available options:
|
||||
#
|
||||
# - resize: Resizes the image to 64x64 pixels if it isn't these dimensions already.
|
||||
# - center: Doesn't resize the image, but instead tries to center it as good as possible in a 64x64 area.
|
||||
# - none: Doesn't resize the image and leaves it positioned at x 0 and y 0 (top-left) of the 64x64 area.
|
||||
#
|
||||
# Setting any not listed option or leaving this blank/removing it sets the option to resize.
|
||||
#
|
||||
faviconStrategy: 'resize'
|
||||
|
||||
#
|
||||
# Options to disable while the Maintenance Plugin is present and Maintenance Mode is active.
|
||||
#
|
||||
@@ -516,7 +531,7 @@ disableDuringMaintenance:
|
||||
# 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.
|
||||
#
|
||||
configVersion: 8
|
||||
configVersion: 9
|
||||
```
|
||||
///
|
||||
|
||||
@@ -535,14 +550,14 @@ There are certain files and folders that get created when certain events happen:
|
||||
|
||||
Creating your first profile is relatively simple.
|
||||
|
||||
It's best to open the `default.yml` file located inside `profiles` with the file editor of your choice ([:simple-vscodium: VSCodeium](https://vscodium.com/) or [:simple-notepadplusplus: Notepad++](https://notepad-plus-plus.org/) are recommended).
|
||||
It's best to open the `default.yml` file located inside `profiles` with the file editor of your choice ([:simple-vscodium: VSCodeium](https://vscodium.com/){ target="_blank" rel="nofollow" } or [:simple-notepadplusplus: Notepad++](https://notepad-plus-plus.org/){ target="_blank" rel="nofollow" } are recommended).
|
||||
This file should contain all available options that you can set and alter.
|
||||
|
||||
Edit the options to whatever you like. All text-based options, except [`condition`](../profiles/index.md#condition), support [MiniMessage formatting](../profiles/formatting.md).
|
||||
Hexadecimal (RGB) colors are supported, however, only the [`motd` option](../profiles/index.md#motd) may display them and only for MC 1.16+ clients. Any other option will have the color down-sampled to the nearest supported color code.
|
||||
Edit the options to whatever you like. All text-based options, except [`condition`](../profiles/options/condition.md), support [MiniMessage formatting](../profiles/formatting.md).
|
||||
Hexadecimal (RGB) colors are supported, however, only the [`motd` option](../profiles/options/motd.md) may display them and only for MC 1.16+ clients. Any other option will have the color down-sampled to the nearest supported color code.
|
||||
|
||||
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.
|
||||
All you need to know is, that a bare-bones server list profile requires a valid [priority](../profiles/options/priority.md) and at least one of the other options (except condition) to be present.
|
||||
|
||||
To give an example is here a basic profile that only modifies the MOTD and nothing else:
|
||||
```yaml title="default.yml"
|
||||
@@ -555,10 +570,10 @@ motd:
|
||||
|
||||
### Additional profiles
|
||||
|
||||
Additional profiles can be created to display different content under specific situations. To create a new file, either manually create a YAML file in the `profiles` folder, or use [`/asl profiles add <name>`](../commands/index.md#profiles) to have one created for you. In either case is it recommended to only use alphanummeric (`a-z` abd `0-9`) characters, dashes and underscores for the file name. You should also choose a name that fits the purpose of the file (i.e. for a profile that displays stuff when someone is banned, name it `banned.yml`).
|
||||
Additional profiles can be created to display different content under specific situations. To create a new file, either manually create a YAML file in the `profiles` folder, or use [`/asl profiles add {name}`](../commands/profiles.md#add) to have one created for you. In either case is it recommended to only use alphanummeric (`a-z` abd `0-9`) characters, dashes and underscores for the file name. You should also choose a name that fits the purpose of the file (i.e. for a profile that displays stuff when someone is banned, name it `banned.yml`).
|
||||
|
||||
In case you manually created a YAML file, make sure it contains the [`priority`](../profiles/index.md#priority) setting and one of the other settings, to have a valid profile.
|
||||
You should also add a [`condition`](../profiles/index.md#condition) to ensure that the profile is only loaded when needed. The [Expressions page](../profiles/expressions.md) covers what counts as valid expressions and conditions.
|
||||
In case you manually created a YAML file, make sure it contains the [`priority`](../profiles/options/priority.md) setting and one of the other settings, to have a valid profile.
|
||||
You should also add a [`condition`](../profiles/options/condition.md) to ensure that the profile is only loaded when needed. The [Expressions page](../profiles/expressions.md) covers what counts as valid expressions and conditions.
|
||||
Do note that the plugin goes through the profiles in order of priority, starting with the highest number first, picking the first one that returns a `condition` returning true.
|
||||
|
||||
/// info | Note about Condition
|
||||
@@ -582,7 +597,7 @@ The [Examples page](../examples/index.md) contains more examples of different se
|
||||
## 4. Loading profiles { #loading-profiles }
|
||||
|
||||
Once you've set up your server list profile(s) is it time to load it/them.
|
||||
To do this, simply run `/asl reload` as player (Requires permission `advancedserverlist.admin` or `advancedserverlist.command.reload`) or `asl reload` through the Server/Proxy console.
|
||||
To do this, simply run [`/asl reload`](../commands/reload.md).
|
||||
|
||||
The plugin should then load any valid YAML file inside the `profiles` folder to then use.
|
||||
|
||||
|
||||
@@ -22,13 +22,25 @@ you can click the image to be sent to the actual video.
|
||||
|
||||
**Video Language:** :flag_gb: English
|
||||
|
||||
[](https://youtube.com/watch?v=9cU0uUWHOO0){ target="_blank" rel="nofollow" }
|
||||
[{ loading="lazy" }](https://youtube.com/watch?v=9cU0uUWHOO0){ target="_blank" rel="nofollow" }
|
||||
|
||||
### Ajneb97
|
||||
|
||||
**Video Language:** :flag_es: Spanish
|
||||
|
||||
[](https://youtube.com/watch?v=rIbljm_4HVI){ target="_blank" rel="nofollow" }
|
||||
[{ loading="lazy" }](https://youtube.com/watch?v=rIbljm_4HVI){ target="_blank" rel="nofollow" }
|
||||
|
||||
### faajrikha
|
||||
|
||||
**Video Language:** :flag_id: Indonesian
|
||||
|
||||
[{ loading="lazy" }](https://www.youtube.com/watch?v=-p938rOmqy4){ target="_blank" rel="nofollow" }
|
||||
|
||||
### FINNI GAMER
|
||||
|
||||
**Video Language:** :flag_de: German
|
||||
|
||||
[{ loading="lazy" }](https://www.youtube.com/watch?v=1Kh3cPMDd0c){ target="_blank" rel="nofollow" }
|
||||
|
||||
## Text Tutorials
|
||||
|
||||
|
||||
+12
-4
@@ -43,8 +43,7 @@ AdvancedServerList supports the following platforms:
|
||||
|
||||
## Pages
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
/// html | div.grid.cards
|
||||
- [:octicons-milestone-24: **Getting Started**](getting-started/index.md)
|
||||
|
||||
----
|
||||
@@ -62,6 +61,16 @@ AdvancedServerList supports the following platforms:
|
||||
----
|
||||
|
||||
A list of all available commands in AdvancedServerList.
|
||||
|
||||
----
|
||||
|
||||
**Other Pages:**
|
||||
|
||||
- [/asl clearcache](commands/clearcache.md)
|
||||
- [/asl help](commands/help.md)
|
||||
- [/asl migrate](commands/migrate.md)
|
||||
- [/asl profiles](commands/profiles.md)
|
||||
- [/asl reload](commands/reload.md)
|
||||
|
||||
- [:octicons-note-24: **Profiles**](profiles/index.md)
|
||||
|
||||
@@ -134,5 +143,4 @@ AdvancedServerList supports the following platforms:
|
||||
- [:octicons-stop-24: BanPlugins Addon](addons/first-party/banplugins.md)
|
||||
- Third Party
|
||||
- [:octicons-eye-closed-24: SayanVanish](addons/third-party/sayanvanish.md)
|
||||
|
||||
</div>
|
||||
///
|
||||
@@ -9,8 +9,7 @@ icon: octicons/file-directory-symlink-24
|
||||
The below pages show guides on how to migrate from another plugin to AdvancedServerList.
|
||||
These pages may include important information about the migration process and what you may have to do before, during or after the process.
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
/// html | div.grid.cards
|
||||
- [**MiniMOTD**](plugins/minimotd.md)
|
||||
|
||||
----
|
||||
@@ -22,16 +21,14 @@ These pages may include important information about the migration process and wh
|
||||
----
|
||||
|
||||
Migrate from the Plugin [ServerListPlus](https://github.com/Minecrell/ServerListPlus){ target="_blank" rel="nofollow" }.
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
## AdvancedServerList
|
||||
|
||||
The below pages show guides on how to migrate from one version to another of AdvancedServerList.
|
||||
These guides are only for the Server List Profile files, as the config.yml gets automatically migrated (Feature since v3.1.0).
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
/// html | div.grid.cards
|
||||
- [**v3.8.0 to v3.9.0**](versions/v3.8.0-to-v3.9.0.md)
|
||||
|
||||
----
|
||||
@@ -61,5 +58,4 @@ These guides are only for the Server List Profile files, as the config.yml gets
|
||||
----
|
||||
|
||||
Migrate from version 1.5.3 to 1.6.0.
|
||||
|
||||
</div>
|
||||
///
|
||||
@@ -11,7 +11,7 @@ Version `4.10.0` added support for migrating your existing `main.conf` configura
|
||||
|
||||
## How to Migrate
|
||||
|
||||
Execute the command [`/asl migrate minimotd`](../../commands/index.md#migrate) to start the migration process. Make sure the `main.conf` file is present in `/plugins/MiniMOTD/` (`minimotd-velocity` on Velocity).
|
||||
Execute the command [`/asl migrate minimotd`](../../commands/migrate.md) to start the migration process. Make sure the `main.conf` file is present in `/plugins/MiniMOTD/` (`minimotd-velocity` on Velocity).
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@@ -28,13 +28,15 @@ The following placeholders get converted:
|
||||
|
||||
### Colors/Formatting
|
||||
|
||||
The following color and formatting codes get converted[^1]:
|
||||
The following color and formatting codes get converted[^1^](#n1):
|
||||
|
||||
| Color/Formatting code | Conversion |
|
||||
|--------------------------------------------|-------------------------------------------------------------------------------|
|
||||
| `&<color/format>` | Corresponding color/formatting code in MiniMessage (i.e. `&1 -> <dark_blue>`) |
|
||||
| `&#<hexcode>` | `<#<hexcode>>` |
|
||||
| `%gradient#<start>#<end>%<text>%gradient%` | `<gradient:#<start>:#<end>><text></gradient>` |
|
||||
| `&{color/format}` | Corresponding color/formatting code in MiniMessage (i.e. `&1 -> <dark_blue>`) |
|
||||
| `&#{hexcode}` | `#!mm <#{hexcode}>` |
|
||||
| `%gradient#{start}#{end}%{text}%gradient%` | `#!mm <gradient:#{start}:#{end}>{text}</gradient>` |
|
||||
|
||||
<small>^1^{ #n1 }Conversion is done lazily and without context, which means that a text such as `&aHello &l%player%&a!` will be converted to `#!mm <green>Hello <bold>${player name}<green>!` when it should be `#!mm <green>Hello <bold>${player name}</bold>!`</small>
|
||||
|
||||
### Favicon options
|
||||
|
||||
@@ -42,13 +44,13 @@ The following Favicon options get converted into an equivalent one:
|
||||
|
||||
| Option | Conversion |
|
||||
|---------|---------------------------------------------------------------------------------|
|
||||
| `Heads` | `https://mc-heads.net/avatar/<entry>/64/nohelm` |
|
||||
| `Heads` | `https://mc-heads.net/avatar/{entry}/64/nohelm` |
|
||||
| `Helms` | Returned as-is with [placeholders replaced](#placeholders). |
|
||||
| `Files` | Only `.png` files will be included with [placeholders replaced](#placeholders). |
|
||||
|
||||
## How to Migrate
|
||||
|
||||
Execute the command [`/asl migrate serverlistplus`](../../commands/index.md#migrate) to start the migration process. Make sure that ServerListPlus is present and enabled.
|
||||
Execute the command [`/asl migrate serverlistplus`](../../commands/migrate.md) to start the migration process. Make sure that ServerListPlus is present and enabled.
|
||||
|
||||
## Example
|
||||
|
||||
@@ -275,8 +277,4 @@ playerCount:
|
||||
amount: 0
|
||||
favicon: ''
|
||||
```
|
||||
///
|
||||
|
||||
[^1]:
|
||||
Converting of color and formatting codes is done lazely and without context.
|
||||
This means that a text such as `&aHello &l%player%&a!` gets converted into `<aqua>Hello <bold>${player name}<aqua>!` when it actually should be `<aqua>Hello <bold>${player name}</bold>!`
|
||||
///
|
||||
@@ -5,7 +5,7 @@ icon: octicons/arrow-right-24
|
||||
# < v3.7.0 to v3.7.0
|
||||
|
||||
Version 3.7.0 of AdvancedServerList brought significant changes to its conditions system.
|
||||
Namely, the `conditions` option is now deprecated and planned for removal in a future release of the Plugin, and the new [`condition`](../../profiles/index.md#condition) option should now be used instead.
|
||||
Namely, the `conditions` option is now deprecated and planned for removal in a future release of the Plugin, and the new [`condition`](../../profiles/options/condition.md) option should now be used instead.
|
||||
|
||||
## Migration
|
||||
|
||||
|
||||
@@ -2,105 +2,107 @@
|
||||
icon: octicons/file-code-24
|
||||
---
|
||||
|
||||
Expressions are part of a Server List Profile's condition system and allows you to define when a profile should and should not be displayed.
|
||||
The condition of a Server List Profile consists of one or multiple expressions.
|
||||
The complete expression should return a boolean. If not, will the returned value be converted based on the following rules:
|
||||
|
||||
This page covers what the Expression system of AdvancedServerList offers and can do.
|
||||
- Numbers will be converted to true, if not `0`
|
||||
- Strings will be converted to true, if equal to `"true"`
|
||||
|
||||
## Content
|
||||
The content below lists all supported forms of expressions that can be used to form a condition:
|
||||
|
||||
- [Types](#types)
|
||||
- [Literals](#literals)
|
||||
- [Numbers](#numbers)
|
||||
- [Strings](#strings)
|
||||
- [Booleans](#booleans)
|
||||
- [Placeholders](#placeholders)
|
||||
- [Binary Operators](#binary-operators)
|
||||
- [Parenthesis](#parenthesis)
|
||||
- [Negation](#negation)
|
||||
- [Credits](#credits)
|
||||
## Literals
|
||||
|
||||
## Types
|
||||
The following values are treated as literal and can form a valid expression.
|
||||
|
||||
An expression contains different types of components that are evaluated to return a boolean output of either `true` or `false`.
|
||||
Depending on the type(s) will the output be differently understood and handled.
|
||||
### Numbers
|
||||
|
||||
### Literals
|
||||
|
||||
The following cases are considered literal values:
|
||||
|
||||
#### Numbers
|
||||
|
||||
Any number is considered an expression, meaning the below examples are considered valid:
|
||||
Any postive or negative number with or without decimal points can form a valid expression.
|
||||
|
||||
/// example | Examples
|
||||
```ruby
|
||||
0
|
||||
1000
|
||||
-7
|
||||
47.2
|
||||
100
|
||||
-1.0
|
||||
10.2
|
||||
```
|
||||
///
|
||||
|
||||
#### Strings
|
||||
### Strings
|
||||
|
||||
A String in single or double quotes is a valid expression.
|
||||
Any quoted String can form a valid expression.
|
||||
|
||||
/// warning | Important
|
||||
Specific keywords will be treated as [Binary Operators](#binary-operators) even if they are part of a word.
|
||||
As an example, `Sand` would cause the expression engine to see `S AND` due to parts of the word matching `and`.
|
||||
|
||||
To avoid this is it very important to always surround Strings with single or double quotes, as that tells the expression engine to treat as a String.
|
||||
/// note
|
||||
Always surround Strings with single or double quotes to avoid ambiguities.
|
||||
The parser may understand specific characters as [binary operands](#binary-operators) should they match an existing text causing issues. Wrapping a String in single or double quotes forces it to treat the value as a String literal.
|
||||
///
|
||||
|
||||
/// example | Examples
|
||||
```ruby
|
||||
"Hello World!"
|
||||
""
|
||||
''
|
||||
```
|
||||
///
|
||||
|
||||
#### Booleans
|
||||
### Booleans
|
||||
|
||||
Strings `true` and `false` are treated as boolean literals.
|
||||
|
||||
### Placeholders
|
||||
|
||||
Any [placeholder](placeholders.md) is a valid expression.
|
||||
Words `true` and `false` (case insensitive) are treated as literal boolean values - unless quoted - and can form valid expressions.
|
||||
|
||||
/// example | Examples
|
||||
```ruby
|
||||
${player protocol}
|
||||
${player name}
|
||||
true
|
||||
false
|
||||
```
|
||||
///
|
||||
|
||||
## Placeholders
|
||||
|
||||
[Placeholders](placeholders.md) are resolved into corresponding [Literals](#literals) and can therefore be valid expressions.
|
||||
|
||||
/// example | Examples
|
||||
```ruby
|
||||
${player name}
|
||||
${player protocol}
|
||||
|
||||
${server playersOnline}
|
||||
${server host}
|
||||
```
|
||||
///
|
||||
|
||||
### Binary Operators
|
||||
## Binary Operators
|
||||
|
||||
`<expression> <binary operator> <expression>` is a valid expression.
|
||||
Binary operators can be used to combine multiple expressions to form a new one.
|
||||
|
||||
### Boolean Binary Operators
|
||||
|
||||
The following binary operators can be used for boolean evaluation:
|
||||
|
||||
| Operator | True if | Case Sensitive? |
|
||||
|---------------|-------------------------------------------------------------------------------|-----------------|
|
||||
| `and` / `&&` | Both expressions return true. | No |
|
||||
| `or` / `\|\|` | Either expression returns true. | No |
|
||||
| `==` / `=` | Both expressions are equal (Case sensitive). | Yes |
|
||||
| `=~` / `~` | Both expressions are equal (Not Case sensitive). | No |
|
||||
| `!=` | Both expressions are not equal (Case sensitive). | Yes |
|
||||
| `!~` | Both expressions are not equal (Not case sensitive). | No |
|
||||
| `\|-` | Left expression starts with right expression (Case sensitive). | Yes |
|
||||
| `\|~` | Left expression starts with right expression (Not case sensitive). | No |
|
||||
| `-\|` | Left expression ends with right expression (Case sensitive). | Yes |
|
||||
| `~\|` | Left expression ends with right expression (Not case sensitive). | No |
|
||||
| `<_` | Left expression contains right expression (Case sensitive). | Yes |
|
||||
| `<~` | Left expression contains right expression (Not case sensitive). | No |
|
||||
| `<` | Left expression is less than the right expression.^[1](#n1)^ | No |
|
||||
| `<=` | Left expression is less than, or equal to, the right expression.^[1](#n1)^ | No |
|
||||
| `>` | Left expression is larger than the right expression.^[1](#n1)^ | No |
|
||||
| `>=` | Left expression is larger than, or equal to, the right expression.^[1](#n1)^ | No |
|
||||
| Operator | True if | Case Sensitive? |
|
||||
|---------------|------------------------------------------------------------------------------|-----------------|
|
||||
| `and` / `&&` | Both expressions return true. | No |
|
||||
| `or` / `\|\|` | Either expression returns true. | No |
|
||||
| `==` / `=` | Both expressions are equal. | Yes |
|
||||
| `=~` / `~` | Both expressions are equal. | No |
|
||||
| `!=` | Both expressions are not equal. | Yes |
|
||||
| `!~` | Both expressions are not equal. | No |
|
||||
| `\|-` | Left expression starts with right expression. | Yes |
|
||||
| `\|~` | Left expression starts with right expression. | No |
|
||||
| `-\|` | Left expression ends with right expression. | Yes |
|
||||
| `~\|` | Left expression ends with right expression. | No |
|
||||
| `<_` | Left expression contains right expression. | Yes |
|
||||
| `<~` | Left expression contains right expression. | No |
|
||||
| `<` | Left expression is less than the right expression.^[1](#n1)^ | No |
|
||||
| `<=` | Left expression is less than, or equal to, the right expression.^[1](#n1)^ | No |
|
||||
| `>` | Left expression is larger than the right expression.^[1](#n1)^ | No |
|
||||
| `>=` | Left expression is larger than, or equal to, the right expression.^[1](#n1)^ | No |
|
||||
|
||||
/// example | Examples
|
||||
```ruby
|
||||
${player name} != "Anonymous"
|
||||
763 > ${player protocol} > 758
|
||||
${player hasPlayedBefore} and ${player isBanned} == "false"
|
||||
```
|
||||
///
|
||||
|
||||
### Other Binary Operators
|
||||
|
||||
These additional binary operators can also be used to perform certain actions:
|
||||
|
||||
@@ -112,22 +114,26 @@ These additional binary operators can also be used to perform certain actions:
|
||||
| `*` | Multiplies two numbers.^[1](#n1)^ |
|
||||
| `/` | Divides one number by another.^[1](#n1)^ |
|
||||
|
||||
<small>^1^{ #n1 } In case of text will the text length be used to compare against.</small>
|
||||
|
||||
/// example | Examples
|
||||
```ruby
|
||||
${player name} != "Anonymous"
|
||||
763 > ${player protocol} > 758
|
||||
${player hasPlayedBefore} and ${player isBanned} == "false"
|
||||
${player protocol} + 10
|
||||
"<green>" . ${player name}
|
||||
```
|
||||
///
|
||||
|
||||
<small>^1^{ #n1 } In case of text will the text length be used to compare against.</small>
|
||||
## Parenthesis
|
||||
|
||||
### Parenthesis
|
||||
Parenthesis can be used to enclose one or multiple expressions to create a new expression and avoid ambiguities.
|
||||
|
||||
`( <expression> )` is a valid expression.
|
||||
Parenthesis can be used to prevent ambiguities.
|
||||
/// example | Example
|
||||
```ruby
|
||||
(${player protocol} + 10) / 100
|
||||
```
|
||||
///
|
||||
|
||||
### Negation
|
||||
## Negation
|
||||
|
||||
`!` can be used to negate boolean expressions.
|
||||
|
||||
|
||||
+14
-14
@@ -9,7 +9,7 @@ If you have questions, don't hesitate to join the [M.O.S.S. Discord][discord] an
|
||||
|
||||
## Text Formatting
|
||||
|
||||
AdvancedServerList uses the [MiniMessage Text Formatting][minimessage] for all formatting of text options ([`motd`](index.md#motd), [`playerCount -> hover`](index.md#hover) and [`playerCount -> text`](index.md#text)).
|
||||
AdvancedServerList uses the [MiniMessage Text Formatting][minimessage] for all formatting of text options ([`motd`](options/motd.md), [`playerCount -> hover`](options/playercount/hover.md) and [`playerCount -> text`](options/playercount/text.md)).
|
||||
It supports all available [formatting tags][tags] with a [few exceptions and limitations](#exceptions-and-limitations).
|
||||
|
||||
/// note
|
||||
@@ -35,7 +35,7 @@ The reason to only support MiniMessage and not the so-called legacy color and fo
|
||||
Below is a comparison of the same text made in MiniMessage and Color codes.
|
||||
|
||||
//// tab | MiniMessage
|
||||
```
|
||||
```mm
|
||||
<aqua>Hello <green><bold>World! <red>How</bold> are</red> you?
|
||||
```
|
||||
////
|
||||
@@ -59,7 +59,7 @@ The reason to only support MiniMessage and not the so-called legacy color and fo
|
||||
Below is an example of a Gradient starting at `#084CFB` (:octicons-dot-fill-24:{ style="color: #084CFB;" }) and ending at `#ADF3FD` (:octicons-dot-fill-24:{ style="color: #ADF3FD;" }).
|
||||
|
||||
//// tab | MiniMessage
|
||||
```
|
||||
```mm
|
||||
<gradient:#084CFB:#ADF3FD>Hello World!</gradient>
|
||||
```
|
||||
////
|
||||
@@ -78,17 +78,17 @@ In general is MiniMessage a lot easier to manage and read as legacy color codes,
|
||||
Due to the situation MiniMessage is used in are not all of its features available to use.
|
||||
Below is a list of all features that cannot be used by AdvancedServerList, or can only be used by it under specific conditions.
|
||||
|
||||
| Feature | Tag | Supported? |
|
||||
|---------------|------------------------------|------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| RGB Colors | `<#rrggbb>` | Only works properly on `motd` and will be downsampled to the closest named color for the other options. |
|
||||
| RGB Gradients | `<gradient:#rrggbb:#rrggbb>` | Only works properly on `motd` and will be downsampled to the closest named color for the other options. |
|
||||
| Click Actions | `<click:_type_:_value_>` | Tag will be rendered, but clicking the text won't do anything. |
|
||||
| Hover Actions | `<hover:_type_:_value_>` | Tag will be rendered, but hovering the text won't show anything. |
|
||||
| Insertions | `<insertion:_value_>` | Tag will be rendered, but clicking the text won't do anything. |
|
||||
| Font | `<font:_font_>` | May work with the default fonts (`default`, `alt` and `uniform`) and with custom ones should the client already have it. |
|
||||
| Selector | `<selector:_sel_>` | Tag will be rendered, but clicking the text won't do anything. |
|
||||
| Score | `<score:_name_:_objective_>` | Will not render due to requiring the player to be on the server. |
|
||||
| Pride | `<pride[:_flag_]>` | Only works if the server (Paper) or Proxy (Velocity) use `v4.18.0` of MiniMessage. BungeeCord is unaffected due to downloading it. |
|
||||
| Feature | Tag | Supported? |
|
||||
|---------------|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Hex Colors | `#!mm <#rrggbb>` | Only works properly on `motd` and will be downsampled to the closest named color for the other options. |
|
||||
| Hex Gradients | `#!mm <gradient:#rrggbb:#rrggbb>` | Only works properly on `motd` and will be downsampled to the closest named color for the other options. |
|
||||
| Click Actions | `#!mm <click:_type_:_value_>` | Tag will be rendered, but clicking the text won't do anything. |
|
||||
| Hover Actions | `#!mm <hover:_type_:_value_>` | Tag will be rendered, but hovering the text won't show anything. |
|
||||
| Insertions | `#!mm <insertion:_value_>` | Tag will be rendered, but clicking the text won't do anything. |
|
||||
| Font | `#!mm <font:_font_>` | May work with the default fonts (`default`, `alt` and `uniform`) and with custom ones should the client already have it. |
|
||||
| Selector | `#!mm <selector:_sel_>` | Tag will be rendered, but clicking the text won't do anything. |
|
||||
| Score | `#!mm <score:_name_:_objective_>` | Will not render due to requiring the player to be on the server. |
|
||||
| Pride | `#!mm <pride[:_flag_]>` | Only works if the server (Paper) or Proxy (Velocity) use `v4.18.0` of MiniMessage. BungeeCord is unaffected due to downloading the library. |
|
||||
|
||||
## Yaml Formatting
|
||||
|
||||
|
||||
+18
-394
@@ -2,398 +2,22 @@
|
||||
icon: octicons/note-24
|
||||
---
|
||||
|
||||
# Profiles { #profiles-file }
|
||||
|
||||
AdvancedServerList allows you to create multiple so called Server List Profiles.
|
||||
A Server List Profile is a YAML file located in the plugin's `profiles` folder. Each Server List Profile allows you to modify one or multiple aspects of your server's display in a Multiplayer Server list.
|
||||
|
||||
Additionally can [Conditions](#condition) and a [Priority](#priority) be set to set when a specific profile should be displayed to a player.
|
||||
|
||||
## Required Options
|
||||
|
||||
For a Server List Profile to be valid, will it require the following options to be set:
|
||||
|
||||
- A valid [`priority`](#priority) option with a single, whole number.
|
||||
- **At least** one of the following options:
|
||||
- [`profiles`](#profiles) with at least one of the below options set.
|
||||
- [`motd`](#motd) with at least one line to display.
|
||||
- [`favicon`](#favicon) with a non-empty String.
|
||||
- [`playerCount -> hidePlayers`](#hideplayers) with value `true`.
|
||||
- [`playerCount -> hover`](#hover) with at least one line to display.
|
||||
- [`playerCount -> text`](#text) with a non-empty String.
|
||||
|
||||
## Priority
|
||||
|
||||
The Priority option allows you to define what Server List Profile should be chosen first.
|
||||
The plugin will go highest value to lowest value and will select the first Profile that has a [`condition`](#condition) returning `true`.
|
||||
|
||||
Should AdvancedServerList not find any profile with a positive condition will it not modify the server list for the players.
|
||||
|
||||
/// note
|
||||
It is important to note that should no [`condition`](#condition) option be set will it default to `true`, meaning that a profile with priority 1 and no condition will be chosen over a profile with priority 0 and a condition, even if said condition also returns true.
|
||||
///
|
||||
|
||||
## Condition
|
||||
|
||||
The `condition` option allows you to define specific requirements that need to be met to display the profile in question.
|
||||
Not setting this option, or setting it to an empty String (`condition: ''`), will result in `true` being returned.
|
||||
|
||||
The condition option can hold one or multiple expressions. The Expression system is explained on the [Expressions page](expressions.md).
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
condition: '${player isWhitelisted}'
|
||||
|
||||
motd:
|
||||
- '<grey>Hello ${player name}!'
|
||||
- '<grey>Nice to see you.'
|
||||
```
|
||||
///
|
||||
|
||||
## Profiles
|
||||
|
||||
The `profile` option allows you to define a list of all other options, with the exception of [`priority`](#priority), [`condition`](#condition) or itself.
|
||||
|
||||
When multiple entries are defined will AdvancedServerList randomly select one.
|
||||
Should an option exist in the file itself (i.e. [`motd`](#motd)) but not in the selected profiles entry will it be used. This allows you to randomize only one aspect of a Server List Profile while keeping all other options the same.
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
profiles:
|
||||
- motd: # You can also use ['<rainbow>Line1</rainbow>','<rainbow:!>Line 2</rainbow>']
|
||||
- '<rainbow>Line 1</rainbow>'
|
||||
- '<rainbow:!>Line 2</rainbow>'
|
||||
playerCount:
|
||||
text: '<green><bold>Awesome!'
|
||||
- playerCount:
|
||||
text: '<yellow><bold>Also Awesome!'
|
||||
|
||||
# This MOTD is used when the second profiles entry is selected.
|
||||
motd:
|
||||
- '<rainbow:2>Line A</rainbow>'
|
||||
- '<rainbow:!2>Line B</rainbow>'
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
## Motd
|
||||
|
||||
<!-- admo:tip Start a line with <code><center></code> to have it centered. -->
|
||||
|
||||
The `motd` option allows you to alter the "Message of the day" that is being displayed on a server in the multiplayer screen.
|
||||
Please see the [Formatting](formatting.md) for all supported formatting options.
|
||||
|
||||
Multiple, randomly selected, MOTDs can be displayed by using the [`profiles`](#profiles) option.
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- '<rainbow:2>Rainbow Gradient</rainbow>'
|
||||
- '<rainbow:!2>|||||||||||||||||||||||||||||||||||||</rainbow>'
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
## Favicon
|
||||
|
||||
<!-- admo:info Images will be resized to 64x64 pixels. -->
|
||||
|
||||
The `favicon` option can be used to define an image to display in the server list.
|
||||
|
||||
The Value can be one of the following:
|
||||
|
||||
- A URL pointing to a Image file. The URL needs to start with `https://` for it to work.
|
||||
- A filename matching a pre-existing file in the `favicons` folder of the Plugin.
|
||||
- Only PNG files are supported for now and the provided filename needs to end with `.png`
|
||||
- `random` can be used to have the plugin select a random image from the Favicons folder.
|
||||
- A player name or UUID.
|
||||
- `${player name}`, `${player uuid}` or any [placeholder](placeholders.md) that resolves into a player name/UUID can be used.
|
||||
- Uses [mc-heads.net](https://mc-heads.net) to resolve the Player Name/UUID.
|
||||
|
||||
/// details | Why is the favicon from URL/Placeholder not showing?
|
||||
type: question
|
||||
|
||||
AdvancedServerList has to create a Favicon instance to use, as the Proxy/Server doesn't directly use PNG images.
|
||||
This action takes time, so to not unnecessarely delay the Pinged Proxy/Server from showing is this done asynchrnously.
|
||||
This has the issue that the Proxy/Server may be done with handling the Ping before AdvancedServerList is done creating the Favicon, resulting in no favicon being displayed.
|
||||
|
||||
This issue is only present for when using either a URL or a Player name/uuid and not for local favicons, as those are created when the plugin loads.
|
||||
|
||||
Favicons *should* display on the second ping, if pinged within the configured favicon cache time (Default: 1 minute).
|
||||
///
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# Hides the MOTD for demonstration purposes
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
# Placeholder resolves to UUID of Andre_601
|
||||
favicon: '${player uuid}'
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
## PlayerCount
|
||||
|
||||
The `playerCount` option contains various other options that are used to modify the player count (The text next to the ping icon that shows the online and max players of a server).
|
||||
|
||||
### HidePlayers
|
||||
|
||||
The `playerCount -> hidePlayers` option takes a boolean (`true` or `false`) to set whether the player count should be hidden or not.
|
||||
|
||||
When set to true will the player count be replaced with `???`.
|
||||
In addition are the [`playerCount -> text`](#text) and [`playerCount -> hover`](#hover) options ignored.
|
||||
|
||||
If you want to not show any text at all, set this option to `false` (or remove it) and instead use the [`playerCount -> text`](#text) option.
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# Hides the MOTD for demonstration purposes
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
hidePlayers: true
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
### HidePlayersHover
|
||||
|
||||
The `playerCount -> hidePlayersHover` option takes a boolean (`true` or `false`) to set whether the hover displayed on the player count should be hidden or not.
|
||||
|
||||
When set to true will hovering over the player count show nothing.
|
||||
In addition will [`playerCount -> hover`](#hover) not be used.
|
||||
|
||||
### Hover
|
||||
|
||||
The `playerCount -> hover` option allows you to define lines of text to show when a player hovers over the player count with their cursor.
|
||||
|
||||
/// info | Notes
|
||||
Only basic color and formatting codes such as `<aqua>` and `<bold>` are accepted. Hex colors will be downsampled to the closest supported color.
|
||||
///
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# Hides the MOTD for demonstration purposes
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
hover:
|
||||
- '<grey>Line 1'
|
||||
- '<aqua>Line 2'
|
||||
- '<gold>Line 3'
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
### Text
|
||||
|
||||
The `playerCount -> text` option allows you to define a custom text to display instead of the usual `<online>/<max>`.
|
||||
|
||||
Please take note of the following caveats:
|
||||
|
||||
- The plugin won't automatically add the `<online>/<max>` back to the text you set. Instead you'll have to use `${server playersOnline}/${server playersMax}` to recreate this.
|
||||
- The override is done by using the "outdated server" text displayed when a client pings a server that is not compatible. This means that the ping icon will appear crossed out and your server will be seen as "outdated" by the client (When hovering over the ping icon). This can't be avoided nor fixed by the plugin.
|
||||
|
||||
If you want to not show any text, just use a single color (i.e. `text: '<grey>'`) to do so.
|
||||
|
||||
This option only supports basic colors and no HEX colors.
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# Hides the MOTD for demonstration purposes
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
text: '<yellow><bold>Cool text!'
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
### ExtraPlayers
|
||||
|
||||
<!-- admo:warning Using this option overrides the output of the <code>${server playersMax}</code> placeholder (Except in condition). -->
|
||||
|
||||
The `playerCount -> extraPlayers` option contains settings for the "extra players" feature, which adds X to the current online player count and sets it as the server's max player count.
|
||||
|
||||
#### Enabled { #extraplayers-enabled }
|
||||
|
||||
Enables the extraPlayers feature.
|
||||
Use the [`playerCount -> extraPlayers -> amount`](#extraplayers-amount) option to set how much to add to the max players count.
|
||||
|
||||
#### Amount { #extraplayers-amount }
|
||||
|
||||
<!-- admo:info This option does nothing when <code>playerCount -> hidePlayers</code> is enabled. -->
|
||||
|
||||
The `playerCount -> extraPlayers -> amount` option defines how much should be added to the current online player count to then use as max player count.
|
||||
|
||||
Example: Setting this option to `1` while currently 10 players are online will result in `10/11` being displayed on the player count (Assuming it is not being overriden by the [`playerCount -> text`](#text) option).
|
||||
|
||||
You can use placeholders that resolve into numbers for this option.
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# Hides the MOTD for demonstration purposes
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
extraPlayers:
|
||||
enabled: true
|
||||
amount: 1
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
### MaxPlayers
|
||||
|
||||
<!-- admo:info This feature is ignored should <code>playerCount -> extraPlayers</code> be enabled. -->
|
||||
<!-- admo:warning Using this option overrides the output of the <code>${server playersMax}</code> placeholder (Except in condition). -->
|
||||
|
||||
The `playerCount -> maxPlayers` option is similar in nature to the [`playerCount -> extraPlayers`](#extraplayers) option, with the difference that the number set is being used as the max player count, instead of adding it together with the online player count first.
|
||||
|
||||
#### Enabled { #maxplayers-enabled }
|
||||
|
||||
Enables the maxPlayers feature.
|
||||
Use the [`playerCount -> maxPlayers -> amount`](#maxplayers-amount) option to set the max player count itself.
|
||||
|
||||
#### Amount { #maxplayers-amount }
|
||||
|
||||
<!-- admo:info This option does nothing when <code>playerCount -> hidePlayers</code> is enabled. -->
|
||||
|
||||
The `playerCount -> maxPlayers -> amount` option defines the number to use as the server's max players count.
|
||||
Unlike the [`playerCount -> extraPlayers -> amount`](#extraplayers-amount) option does this one not first add the current online player count to the number to then set.
|
||||
|
||||
You can use placeholders that resolve into numbers for this option.
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# Hides the MOTD for demonstration purposes
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
maxPlayers:
|
||||
enabled: true
|
||||
amount: -1
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||
{ loading="lazy" }
|
||||
|
||||
</div>
|
||||
///
|
||||
|
||||
### OnlinePlayers
|
||||
|
||||
<!-- admo:warning Using this option alters the output of <code>playerCount -> extraPlayers</code> -->
|
||||
|
||||
The `playerCount -> onlinePlayers` option contains settings to enable and set the number of players online on the server.
|
||||
|
||||
#### Enabled { #onlineplayers-enabled }
|
||||
|
||||
Enables the online players feature.
|
||||
Use the [`playerCount -> onlinePlayers -> amount`](#onlineplayers-amount) option to set the online players value itself.
|
||||
|
||||
#### Amount { #onlineplayers-amount }
|
||||
|
||||
Sets the number to display as the server's only player count.
|
||||
You can use placeholders that resolve into numbers for this option.
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# Hides the MOTD for demonstration purposes
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
onlinePlayers:
|
||||
enabled: true
|
||||
amount: 10
|
||||
```
|
||||
<div class="result" markdown>
|
||||
|
||||

|
||||
|
||||
</div>
|
||||
# Profiles
|
||||
|
||||
The Server List Profile is a YAML file containing various options to modify and alter the appearance of your server in a player's server list.
|
||||
Below can you find a list of all available options, including explanations and some examples.
|
||||
|
||||
/// html | div.grid.cards
|
||||
- [`priority`](options/priority.md)
|
||||
- [`condition`](options/condition.md)
|
||||
- [`profiles`](options/profiles.md)
|
||||
- [`motd`](options/motd.md)
|
||||
- [`favicon`](options/favicon.md)
|
||||
- [`playerCount -> hidePlayers`](options/playercount/hideplayers.md)
|
||||
- [`playerCount -> hidePlayersHover`](options/playercount/hideplayershover.md)
|
||||
- [`playerCount -> hover`](options/playercount/hover.md)
|
||||
- [`playerCount -> text`](options/playercount/text.md)
|
||||
- [`playerCount -> extraPlayers`](options/playercount/extraplayers.md)
|
||||
- [`playerCount -> maxPlayers`](options/playercount/maxplayers.md)
|
||||
- [`playerCount -> onlinePlayers`](options/playercount/onlineplayers.md)
|
||||
///
|
||||
@@ -0,0 +1,24 @@
|
||||
# Condition
|
||||
|
||||
The `condition` option is a String that allows you to set a single or multiple requirements that need to be fulfilled to display the profile itself.
|
||||
|
||||
The String can contain [any valid expression](../expressions.md) that returns a boolean. Non-boolean values will be converted to one based on their value.
|
||||
|
||||
/// note
|
||||
An empty condition String or no condition will always be treated as a true condition.
|
||||
///
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
priority: 1
|
||||
|
||||
#
|
||||
# This condition returns true if the player's protocol version is
|
||||
# less than 735.
|
||||
#
|
||||
# 735 is the protocol version for 1.16, which means this returns true
|
||||
# if the player uses a version older than MC 1.16.
|
||||
#
|
||||
condition: '${player protocol} <= 735'
|
||||
```
|
||||
@@ -0,0 +1,63 @@
|
||||
# Favicon
|
||||
|
||||
/// info | Favicon Merging (New since 5.6.0)
|
||||
You can define multiple entries to be merged into a single Favicon by separating them with a semicolon.
|
||||
Example: `background.png;${player uuid};foreground.png`
|
||||
///
|
||||
|
||||
The `favicon` option is a String that sets the image that should be displayed in the server list.
|
||||
The final image itself is 64x64 pixels and any images used with a differing size will be automatically resized to fit.
|
||||
|
||||
The option supports specific values:
|
||||
|
||||
- A URL with `https://` at the start that points to an image.
|
||||
- A filename with `.png` extension that matches an existing file in the `favicons` folder of the plugin.
|
||||
- You can use `random` to have the plugin randomly select an image from the folder.
|
||||
- A player name or UUID that will be resolved into a Player head image using https://mc-heads.net{ target="_blank" rel="nofollow" }.
|
||||
- Placeholders that get resolved into a player name or UUID (i.e. `${player name}` or `${player uuid}`) can be used.
|
||||
|
||||
/// details | Why is the favicon from URL/Player name/Player UUID/Placeholder not loading?
|
||||
type: question
|
||||
|
||||
Servers and Proxies don't use the image file directly, but have their own specific Favicon instance.
|
||||
To set the Favicon is AdvancedServerList required to create such a Favicon instance from the provided URL. This process takes a lot of time, so to not slow down the server/proxy more then necessary is this done asynchronously.
|
||||
A downside of this is, that the server/proxy won't wait for the plugin to be done with creating the favicon, which results in the ping event being completed before the plugin could set the Favicon, resulting in none being displayed.
|
||||
|
||||
The created favicon is being cached and *should* display on the next ping, if done so within the configured `faviconCacheTime` (Default: 1 minute).
|
||||
|
||||
This issue only exists for Favicons created from a URL, player name/uuid or Placeholder and doesn't exist for local favicons located in the `favicons` folder as they are converted into Favicon instances during the plugin's startup.
|
||||
///
|
||||
|
||||
## Favicon Resizing
|
||||
|
||||
Any image used that is not 64x64 pixels will by default be resized to be 64x64 pixels.
|
||||
To allow more customization - especially with favicon merging - different modes can be used for images that do not have the right dimensions.
|
||||
The mode used is set in the `faviconStrategy` option in the `config.yml` and can be one of the following options:
|
||||
|
||||
| Mode | Description |
|
||||
|----------|---------------------------------------------------------------------------------------------------------------|
|
||||
| `resize` | Default mode used. Resizes the image to 64x64 pixels. |
|
||||
| `center` | Doesn't resize the image, but centers it as good as possible. |
|
||||
| `none` | Won't resize nor move the image. The image itself will be placed at `0,0` which is the top-left of the image. |
|
||||
|
||||
Please note that the actual favicon displayed will always be 64x64 pixels, even if the image(s) depicted in it aren't.
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
#
|
||||
# In this example is the player Andre_601 watching the server
|
||||
# list, so ${player uuid} is being resolved into their UUID,
|
||||
# resulting in the head of their skin being displayed.
|
||||
#
|
||||
favicon: '${player uuid}'
|
||||
```
|
||||
/// html | div.result
|
||||
{ loading="lazy" }
|
||||
///
|
||||
@@ -0,0 +1,25 @@
|
||||
# Motd
|
||||
|
||||
The `motd` option is a List of Strings that sets the "Message of the day", referring to the two lines of text shown in the Multiplayer Server List.
|
||||
This is the only option that supports RGB colors, if the server and client use at least version 1.16 of Minecraft.
|
||||
|
||||
/// tip | Centering the MOTD
|
||||
Centering the MOTD can be done automatically by prefixing the lines with `<center>` (Even before color and formatting text), but only since version 5.2.0.
|
||||
Before this version, you would need to manually center the text by adding spaces yourself.
|
||||
///
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
#
|
||||
# Creates a MOTD with a smooth Rainbow gradient.
|
||||
#
|
||||
motd:
|
||||
- '<rainbow:2>Rainbow Gradients</rainbow>'
|
||||
- '<rainbow!2>|||||||||||||||||||||||||||||||||||||</rainbow>'
|
||||
```
|
||||
/// html | div.result
|
||||

|
||||
///
|
||||
@@ -0,0 +1,36 @@
|
||||
# ExtraPlayers
|
||||
|
||||
The `extraPlayers` option contains additional options to enable and set the extra players feature.
|
||||
The extra players feature modifies the displayed max players count by taking the current online player count, adding the configured [`amount`](#amount) to it and using that as the number.
|
||||
|
||||
/// warning | Important
|
||||
Using this option will affect the output of the `${server playersMax}` option, except when used within the [`condition`](../condition.md) option.
|
||||
This option is also ignored should the [`hidePlayers`](hideplayers.md) option be enabled.
|
||||
///
|
||||
|
||||
## Enabled
|
||||
|
||||
Sets the enabled state of this option.
|
||||
|
||||
## Amount
|
||||
|
||||
Sets the amount that should be added to the online player count. Negative numbers are supported!
|
||||
Placeholders that resolve into numbers can be used.
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
extraPlayers:
|
||||
enabled: true
|
||||
amount: 1
|
||||
```
|
||||
/// html | div.result
|
||||
{ loading="lazy" }
|
||||
///
|
||||
@@ -0,0 +1,20 @@
|
||||
# HidePlayers
|
||||
|
||||
The `hidePlayers` option is a boolean that sets wether the player count should be displayed or not.
|
||||
When set to `true` will the player counte be replaced with three question marks. This also disables the [`hover`](hover.md) option.
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
hidePlayers: true
|
||||
```
|
||||
/// html | div.result
|
||||
{ loading="lazy" }
|
||||
///
|
||||
@@ -0,0 +1,20 @@
|
||||
# HidePlayersHover
|
||||
|
||||
The `hidePlayersHover` is a boolean that sets wether the hover on the player count should be displayed or not.
|
||||
When set to true will hovering over the player count with your cursor show nothing. This will also disable the [`hover`](hover.md) option.
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
hidePlayersHover: true
|
||||
```
|
||||
/// html | div.result
|
||||
No example image to show :C
|
||||
///
|
||||
@@ -0,0 +1,25 @@
|
||||
# Hover
|
||||
|
||||
The `hover` option is a String list that overrides the Hover of the player count that usually displays the players currently on the server.
|
||||
This option only supports basic color and formatting options, meaning you can't use RGB colors here.
|
||||
|
||||
There can also be an issue with the hover showing "...and X more" at the bottom. This is an issue that cannot be fixed by the plugin itself unfortunately.
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
hover:
|
||||
- '<grey>Line 1'
|
||||
- '<aqua>Line 2'
|
||||
- '<gold>Line 3'
|
||||
```
|
||||
/// html | div.result
|
||||
{ loading="lazy" }
|
||||
///
|
||||
@@ -0,0 +1,14 @@
|
||||
# PlayerCount
|
||||
|
||||
The `playerCount` option contains various options all related to the player count (The text that displays `<online players>/<max players>` on the right side).
|
||||
See below for available options:
|
||||
|
||||
/// html | div.grid.cards
|
||||
- [`hidePlayers`](hideplayers.md)
|
||||
- [`hidePlayersHover`](hideplayershover.md)
|
||||
- [`hover`](hover.md)
|
||||
- [`text`](text.md)
|
||||
- [`extraPlayers`](extraplayers.md)
|
||||
- [`maxPlayers`](maxplayers.md)
|
||||
- [`onlinePlayers`](onlineplayers.md)
|
||||
///
|
||||
@@ -0,0 +1,36 @@
|
||||
# MaxPlayers
|
||||
|
||||
The `maxPlayers` option contains additional options to enable and set the max players feature.
|
||||
The max players feature modifies the displayed max players count by setting the configured [`amount`](#amount) to it.
|
||||
|
||||
/// warning | Important
|
||||
Using this option will affect the output of the `${server playersMax}` option, except when used within the [`condition`](../condition.md) option.
|
||||
This option is also ignored should the [`hidePlayers`](hideplayers.md) or [`extraPlayers`](extraplayers.md) option be enabled.
|
||||
///
|
||||
|
||||
## Enabled
|
||||
|
||||
Sets the enabled state of this option.
|
||||
|
||||
## Amount
|
||||
|
||||
Sets the amount that should be displayed as the max players count!
|
||||
Placeholders that resolve into numbers can be used.
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
maxPlayers:
|
||||
enabled: true
|
||||
amount: -1
|
||||
```
|
||||
/// html | div.result
|
||||
{ loading="lazy" }
|
||||
///
|
||||
@@ -0,0 +1,35 @@
|
||||
# OnlinePlayers
|
||||
|
||||
The `onlinePlayers` option contains additional options to enable and set the online players feature.
|
||||
The online players feature modifies the displayed online players count by setting the configured [`amount`](#amount) to it.
|
||||
|
||||
/// warning | Important
|
||||
This option affects the result of the [`extraPlayers`](extraplayers.md) option.
|
||||
///
|
||||
|
||||
## Enabled
|
||||
|
||||
Sets the enabled state of this option.
|
||||
|
||||
## Amount
|
||||
|
||||
Sets the amount that should be displayed as the online players count!
|
||||
Placeholders that resolve into numbers can be used.
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
onlinePlayers:
|
||||
enabled: true
|
||||
amount: 10
|
||||
```
|
||||
/// html | div.result
|
||||
{ loading="lazy" }
|
||||
///
|
||||
@@ -0,0 +1,20 @@
|
||||
# Text
|
||||
|
||||
The `text` option is a String that sets the text usually displaying the player count.
|
||||
This option only supports basic color and formatting options. In addition will your server be displayed as "outdated" (The ping icon will appear crossed out). This is due to the plugin manipulating the "outdated server/client" text usually displayed if your client and server version do not match. This is an issue that cannot be fixed by the plugin and is something other plugins offering this feature also suffer from.
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
motd:
|
||||
- '<grey>'
|
||||
- '<grey>'
|
||||
|
||||
playerCount:
|
||||
text: '<yellow><bold>Cool text!'
|
||||
```
|
||||
/// html | div.result
|
||||
{ loading="lazy" }
|
||||
///
|
||||
@@ -0,0 +1,10 @@
|
||||
# Priority
|
||||
|
||||
The `priority` option is a number that determines the order in which AdvancedServerList should go through the individual files, should there be multiple.
|
||||
The plugin will go from highest number to lowest number and select the first profile whos [`condition`](condition.md) option returns true.
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
priority: 0
|
||||
```
|
||||
@@ -0,0 +1,50 @@
|
||||
# Profiles
|
||||
|
||||
The `profiles` option is a List option that allows you to define multiple entries for a single file to use, providing a way of randomly displaying an MOTD, Favicon, etc.
|
||||
|
||||
Each list entry can contain any combination of the following options:
|
||||
|
||||
- [`motd`](motd.md)
|
||||
- [`favicon`](favicon.md)
|
||||
- `playerCount`
|
||||
- [`hidePlayers`](playercount/hideplayers.md)
|
||||
- [`hidePlayersHover`](playercount/hideplayershover.md)
|
||||
- [`hover`](playercount/hover.md)
|
||||
- [`text`](playercount/text.md)
|
||||
- [`extraPlayers`](playercount/extraplayers.md)
|
||||
- [`maxPlayers`](playercount/maxplayers.md)
|
||||
- [`onlinePlayers`](playercount/onlineplayers.md)
|
||||
|
||||
When present with at least one entry will the plugin select an entry at random, using the provided option values to display.
|
||||
Should an entry not have an option present will the plugin check the file itself for the option to use. As an example, not setting `favicon` in the list will have AdvancedServerList check the file itself for a `favicon` option to use.
|
||||
This allows you to only randomize a specific option of a profile while keeping the other ones static (i.e. have a randomized MOTD while the Favicon remains the same).
|
||||
|
||||
## Example
|
||||
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
#
|
||||
# This example has two profiles where both change the 'playerCount -> text' option
|
||||
# but only the first entry also changes the motd, resulting in the second one
|
||||
# using the motd option in the file itself.
|
||||
#
|
||||
profiles:
|
||||
- motd: ['<rainbow>Line 1</rainbow>', '<rainbow:!>Line 2</rainbow>']
|
||||
playerCount:
|
||||
text: '<green><bold>Awesome!'
|
||||
- playerCount:
|
||||
text: '<yellow><bold>Also Awesome!'
|
||||
|
||||
#
|
||||
# This MOTD is only used should the second profiles option be picked as it does not
|
||||
# have a motd option set.
|
||||
#
|
||||
motd:
|
||||
- '<rainbow:2>Line A</rainbow>'
|
||||
- '<rainbow:!2>Line B</rainbow>'
|
||||
```
|
||||
/// html | div.result
|
||||
{ loading="lazy" }
|
||||
{ loading="lazy" }
|
||||
///
|
||||
@@ -15,15 +15,15 @@ The following placeholders are available in AdvancedServerList itself. Please no
|
||||
|
||||
These placeholders use the player who pinged the server, to return values. They may require the player to be cached in order to work.
|
||||
|
||||
| Placeholder | Description | Platforms | Cached Player required?^[1](#player-n1)^ |
|
||||
|-----------------------------|-----------------------------------------------------------------|--------------|------------------------------------------|
|
||||
| `${player name}` | The name of the player. | All | Yes^[2](#player-n2)^ |
|
||||
| `${player protocol}` | The protocol version of the player. | All | No |
|
||||
| `${player uuid}` | The UUID of the player. | All | Yes^[3](#player-n3)^ |
|
||||
| `${player version}` | The protocol version of the player as readable MC version. | Velocity | No |
|
||||
| `${player hasPlayedBefore}` | Boolean for whether the player has played on the server before. | Paper | Yes |
|
||||
| `${player isBanned}` | Boolean for whether the player has been banned from the server. | Paper | Yes |
|
||||
| `${player isWhitelisted}` | Boolean for whether the player is whitelisted on the server. | Paper | Yes |
|
||||
| Placeholder | Description | Platforms | Cached Player required?^[1](#player-n1)^ |
|
||||
|-----------------------------|-----------------------------------------------------------------|------------------------|------------------------------------------|
|
||||
| `${player name}` | The name of the player. | <!-- icon:all --> | Yes^[2](#player-n2)^ |
|
||||
| `${player protocol}` | The protocol version of the player. | <!-- icon:all --> | No |
|
||||
| `${player uuid}` | The UUID of the player. | <!-- icon:all --> | Yes^[3](#player-n3)^ |
|
||||
| `${player version}` | The protocol version of the player as readable MC version. | <!-- icon:velocity --> | No |
|
||||
| `${player hasPlayedBefore}` | Boolean for whether the player has played on the server before. | <!-- icon:paper --> | Yes |
|
||||
| `${player isBanned}` | Boolean for whether the player has been banned from the server. | <!-- icon:paper --> | Yes |
|
||||
| `${player isWhitelisted}` | Boolean for whether the player is whitelisted on the server. | <!-- icon:paper --> | Yes |
|
||||
|
||||
<small>^1^{ #player-n1 } When `Yes` is set, requires the player to have joined before while AdvancedServerList was running. Placeholder will not work when `disableCache` is true.</small>
|
||||
|
||||
@@ -35,17 +35,17 @@ These placeholders use the player who pinged the server, to return values. They
|
||||
|
||||
These placeholders use values given by the server/proxy AdvancedServerList runs on.
|
||||
|
||||
| Placeholder | Description | Platforms |
|
||||
|------------------------------|-------------------------------------------------------------------------|-----------|
|
||||
| `${server playersOnline}` | The number of players online on this proxy/server.^[1](#server-n1)^ | All |
|
||||
| `${server playersMax}` | The total number of players that can join this server.^[2](#server-n2)^ | All |
|
||||
| `${server host}` | The domain/IP the player pinged.^[3](#server-n3)^ | All |
|
||||
| `${server whitelistEnabled}` | Whether the whitelist is enabled or not. | Paper |
|
||||
| Placeholder | Description | Platforms |
|
||||
|------------------------------|-------------------------------------------------------------------------|---------------------|
|
||||
| `${server playersOnline}` | The number of players online on this proxy/server.^[1](#server-n1)^ | <!-- icon:all --> |
|
||||
| `${server playersMax}` | The total number of players that can join this server.^[2](#server-n2)^ | <!-- icon:all --> |
|
||||
| `${server host}` | The domain/IP the player pinged.^[3](#server-n3)^ | <!-- icon:all --> |
|
||||
| `${server whitelistEnabled}` | Whether the whitelist is enabled or not. | <!-- icon:paper --> |
|
||||
|
||||
<small>^1^{ #server-n1 } You can provide a comma-separated list of world or server names (based on platform) to return the collective count of players on these worlds/servers.
|
||||
Additionally, when using [`playerCount -> onlinePlayers`](index.md#onlineplayers) will this placeholder return the modified online players count, except when used within the [`condition`](index.md#condition) option.</small>
|
||||
Additionally, when using [`playerCount -> onlinePlayers`](options/playercount/onlineplayers.md) will this placeholder return the modified online players count, except when used within the [`condition`](options/condition.md) option.</small>
|
||||
|
||||
<small>^2^{ #server-n2 } When using either [`playerCount -> extraPlayers`](index.md#extraplayers) or [`playerCount -> maxPlayers`](index.md#maxplayers) will this placeholder return the modified max players count, except when used within the [`condition`](index.md#condition) option.</small>
|
||||
<small>^2^{ #server-n2 } When using either [`playerCount -> extraPlayers`](options/playercount/extraplayers.md) or [`playerCount -> maxPlayers`](options/playercount/maxplayers.md) will this placeholder return the modified max players count, except when used within the [`condition`](options/condition.md) option.</small>
|
||||
|
||||
<small>^3^{ #server-n3 } An optional server name may be provided to display the IP/Domain associated with said server. This only works for the BungeeCord and Velocity version of the plugin.</small>
|
||||
|
||||
@@ -68,7 +68,7 @@ Servers are pinged every 10 seconds by the plugin and cached for that time perio
|
||||
|
||||
### Maintenance
|
||||
|
||||
These placeholders require the [Maintenance](https://hangar.papermc.io/kennytv/Maintenance) plugin to work.
|
||||
These placeholders require the [Maintenance](https://hangar.papermc.io/kennytv/Maintenance){ target="_blank" rel="nofollow" } plugin to work.
|
||||
|
||||
| Placeholder | Description |
|
||||
|-------------------------------------|----------------------------------------------------------------|
|
||||
@@ -112,4 +112,4 @@ Placeholders from PlaceholderAPI Expansions can be used in AdvancedServerList us
|
||||
PlaceholderAPI placeholders can be used both on the Server (Paper) and on the proxy (BungeeCord, Velocity) version of AdvancedServerList.
|
||||
However, the Proxy version requires the usage of [PAPIProxyBridge] to function properly.
|
||||
|
||||
Placeholders can also not be used within the [`condition`](index.md#condition) option of a Server List Profile.
|
||||
Placeholders can also not be used within the [`condition`](options/condition.md) option of a Server List Profile.
|
||||
+25
-1
@@ -102,6 +102,7 @@ markdown_extensions:
|
||||
emoji_index: !!python/name:material.extensions.emoji.twemoji
|
||||
emoji_generator: !!python/name:material.extensions.emoji.to_svg
|
||||
- pymdownx.highlight:
|
||||
- pymdownx.inlinehilite:
|
||||
- pymdownx.magiclink:
|
||||
- pymdownx.superfences:
|
||||
- pymdownx.snippets:
|
||||
@@ -125,20 +126,43 @@ markdown_extensions:
|
||||
- pymdownx.blocks.tab:
|
||||
alternate_style: true
|
||||
- pymdownx.blocks.details:
|
||||
- pymdownx.blocks.html:
|
||||
- pymdownx.caret:
|
||||
|
||||
hooks:
|
||||
- docs/.hooks/badges.py
|
||||
- docs/.hooks/replacer.py
|
||||
- docs/.hooks/platforms.py
|
||||
|
||||
nav:
|
||||
- Home: index.md
|
||||
- Getting Started:
|
||||
- getting-started/index.md
|
||||
- Tutorials: getting-started/tutorials.md
|
||||
- Commands: commands/index.md
|
||||
- Commands:
|
||||
- commands/index.md
|
||||
- commands/clearcache.md
|
||||
- commands/help.md
|
||||
- commands/migrate.md
|
||||
- commands/profiles.md
|
||||
- commands/reload.md
|
||||
- Profiles:
|
||||
- profiles/index.md
|
||||
- Options:
|
||||
- Priority: profiles/options/priority.md
|
||||
- Condition: profiles/options/condition.md
|
||||
- Profiles: profiles/options/profiles.md
|
||||
- Motd: profiles/options/motd.md
|
||||
- Favicon: profiles/options/favicon.md
|
||||
- PlayerCount:
|
||||
- profiles/options/playercount/index.md
|
||||
- HidePlayers: profiles/options/playercount/hideplayers.md
|
||||
- HidePlayersHover: profiles/options/playercount/hideplayershover.md
|
||||
- Hover: profiles/options/playercount/hover.md
|
||||
- Text: profiles/options/playercount/text.md
|
||||
- ExtraPlayers: profiles/options/playercount/extraplayers.md
|
||||
- MaxPlayers: profiles/options/playercount/maxplayers.md
|
||||
- OnlinePlayers: profiles/options/playercount/onlineplayers.md
|
||||
- Expressions: profiles/expressions.md
|
||||
- Formatting: profiles/formatting.md
|
||||
- Placeholders: profiles/placeholders.md
|
||||
|
||||
+1
-2
@@ -100,7 +100,7 @@
|
||||
<dependency>
|
||||
<groupId>com.viaversion</groupId>
|
||||
<artifactId>viaversion-api</artifactId>
|
||||
<version>5.2.1</version>
|
||||
<version>5.4.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -188,5 +188,4 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -70,6 +70,14 @@ public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon
|
||||
|
||||
@Override
|
||||
public void onEnable(){
|
||||
try{
|
||||
// Required for the Cloud command Framework to function.
|
||||
Class.forName("io.papermc.paper.command.brigadier.CommandSourceStack");
|
||||
}catch(ClassNotFoundException ex){
|
||||
printOutdatedPaper();
|
||||
return;
|
||||
}
|
||||
|
||||
this.commandHandler = new PaperCommandManagerInterface(this);
|
||||
this.core = AdvancedServerList.init(this, new PaperPlayerPlaceholders(), new PaperServerPlaceholders(this));
|
||||
|
||||
@@ -230,4 +238,17 @@ public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon
|
||||
private String getOldVersion(){
|
||||
return getServer().getName() + " " + getServer().getVersion();
|
||||
}
|
||||
|
||||
private void printOutdatedPaper(){
|
||||
getPluginLogger().warn("================================================================");
|
||||
getPluginLogger().warn("OUTDATED PAPER VERSION DETECTED!");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("AdvancedServerList detected an outdated Paper version.");
|
||||
getPluginLogger().warn("The plugin requires at least 1.20.6 of Paper due to required");
|
||||
getPluginLogger().warn("classes only existing within this version onwards.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("Please use at least Paper 1.20.6 or downgrade AdvancedServerList");
|
||||
getPluginLogger().warn("to v5.4.1.");
|
||||
getPluginLogger().warn("================================================================");
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ description: '${plugin.description}'
|
||||
|
||||
main: 'ch.andre601.advancedserverlist.paper.PaperCore'
|
||||
|
||||
api-version: '1.20'
|
||||
api-version: '1.20.6'
|
||||
|
||||
folia-supported: true
|
||||
|
||||
@@ -22,33 +22,4 @@ dependencies:
|
||||
required: false
|
||||
ServerListPlus:
|
||||
load: BEFORE
|
||||
required: false
|
||||
|
||||
# This is actually supported(?)
|
||||
permissions:
|
||||
advancedserverlist.*:
|
||||
description: 'Grants access to all permissions'
|
||||
default: op
|
||||
children:
|
||||
- 'advancedserverlist.admin'
|
||||
advancedserverlist.admin:
|
||||
description: 'Grants access to all permissions'
|
||||
default: op
|
||||
children:
|
||||
- 'advancedserverlist.command.*'
|
||||
- 'advancedserverlist.updatecheck'
|
||||
advancedserverlist.command.*:
|
||||
description: 'Grants access to all commands'
|
||||
default: op
|
||||
children:
|
||||
- 'advancedserverlist.command.help'
|
||||
- 'advancedserverlist.command.reload'
|
||||
advancedserverlist.command.help:
|
||||
description: 'Grants access to /asl help'
|
||||
default: op
|
||||
advancedserverlist.command.reload:
|
||||
description: 'Grants access to /asl reload'
|
||||
default: op
|
||||
advancedserverlist.updatecheck:
|
||||
description: 'Notifies you of new updates when joining the server'
|
||||
default: op
|
||||
required: false
|
||||
@@ -41,23 +41,23 @@
|
||||
|
||||
<project.build.build_id/>
|
||||
|
||||
<plugin.version>5.5.1</plugin.version>
|
||||
<plugin.version>5.6.0</plugin.version>
|
||||
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
|
||||
|
||||
<api.version>4.1.0</api.version>
|
||||
<api.version>4.1.1</api.version>
|
||||
|
||||
<!-- Adventure versions -->
|
||||
<dependency.adventure-api>4.18.0</dependency.adventure-api>
|
||||
<dependency.adventure-text-minimessage>4.18.0</dependency.adventure-text-minimessage>
|
||||
<dependency.adventure-text-serializer-legacy>4.18.0</dependency.adventure-text-serializer-legacy>
|
||||
<dependency.adventure-platform-bungeecord>4.3.4</dependency.adventure-platform-bungeecord>
|
||||
<dependency.adventure-api>4.23.0</dependency.adventure-api>
|
||||
<dependency.adventure-text-minimessage>4.23.0</dependency.adventure-text-minimessage>
|
||||
<dependency.adventure-text-serializer-legacy>4.23.0</dependency.adventure-text-serializer-legacy>
|
||||
<dependency.adventure-platform-bungeecord>4.4.0</dependency.adventure-platform-bungeecord>
|
||||
<!-- Configurate version -->
|
||||
<dependency.configurate-yaml>4.1.2</dependency.configurate-yaml>
|
||||
<dependency.configurate-yaml>4.2.0</dependency.configurate-yaml>
|
||||
<!-- Cloud versions -->
|
||||
<dependency.cloud-annotations>2.0.0</dependency.cloud-annotations>
|
||||
<dependency.cloud-bungee>2.0.0-beta.10</dependency.cloud-bungee>
|
||||
<dependency.cloud-paper>2.0.0-beta.10</dependency.cloud-paper>
|
||||
<dependency.cloud-velocity>2.0.0-beta.10</dependency.cloud-velocity>
|
||||
<dependency.cloud-bungee>2.0.0-SNAPSHOT</dependency.cloud-bungee>
|
||||
<dependency.cloud-paper>2.0.0-SNAPSHOT</dependency.cloud-paper>
|
||||
<dependency.cloud-velocity>2.0.0-SNAPSHOT</dependency.cloud-velocity>
|
||||
<dependency.cloud-minecraft-extras>2.0.0-beta.10</dependency.cloud-minecraft-extras>
|
||||
</properties>
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.13.0</version>
|
||||
<version>3.14.0</version>
|
||||
<configuration>
|
||||
<compilerArgs>
|
||||
<arg>-parameters</arg>
|
||||
|
||||
+54
-15
@@ -1,8 +1,14 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["config:base", "group:allNonMajor"],
|
||||
"dependencyDashboard": false,
|
||||
"labels": ["PR Type/Dependency Update"],
|
||||
"extends": [
|
||||
"config:recommended",
|
||||
"group:allNonMajor"
|
||||
],
|
||||
"dependencyDashboard": true,
|
||||
"configMigration": true,
|
||||
"labels": [
|
||||
"PR Type/Dependency Update"
|
||||
],
|
||||
"ignoreDeps": [
|
||||
"ch.andre601.advancedserverlist:parent",
|
||||
"ch.andre601.advancedserverlist:core"
|
||||
@@ -71,35 +77,68 @@
|
||||
"https://s01.oss.sonatype.org/content/repositories/snapshots/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Ignore 2.0.0-SNAPSHOT of cloud",
|
||||
"matchPackageNames": [
|
||||
"org.incendo:cloud-bungee",
|
||||
"org.incendo:cloud-paper",
|
||||
"org.incendo:cloud-velocity"
|
||||
],
|
||||
"allowedVersions": "!/2\\.0\\.0-SNAPSHOT$/"
|
||||
},
|
||||
{
|
||||
"description": "Apply label for Bukkit platform",
|
||||
"matchFileNames": ["bukkit/pom.xml"],
|
||||
"addLabels": ["PR Target/Bukkit"]
|
||||
"matchFileNames": [
|
||||
"bukkit/pom.xml"
|
||||
],
|
||||
"addLabels": [
|
||||
"PR Target/Bukkit"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Apply label for BungeeCord platform",
|
||||
"matchFileNames": ["bungeecord/pom.xml"],
|
||||
"addLabels": ["PR Target/BungeeCord"]
|
||||
"matchFileNames": [
|
||||
"bungeecord/pom.xml"
|
||||
],
|
||||
"addLabels": [
|
||||
"PR Target/BungeeCord"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Apply label for Core platform",
|
||||
"matchFileNames": ["core/pom.xml"],
|
||||
"addLabels": ["PR Target/Core"]
|
||||
"matchFileNames": [
|
||||
"core/pom.xml"
|
||||
],
|
||||
"addLabels": [
|
||||
"PR Target/Core"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Apply label for Velocity platform",
|
||||
"matchFileNames": ["velocity/pom.xml"],
|
||||
"addLabels": ["PR Target/Velocity"]
|
||||
"matchFileNames": [
|
||||
"velocity/pom.xml"
|
||||
],
|
||||
"addLabels": [
|
||||
"PR Target/Velocity"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Apply label for MkDocs",
|
||||
"matchFileNames": ["requirements.txt"],
|
||||
"addLabels": ["PR Target/MkDocs"]
|
||||
"matchFileNames": [
|
||||
"requirements.txt"
|
||||
],
|
||||
"addLabels": [
|
||||
"PR Target/MkDocs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Apply label for Woodpecker-CI",
|
||||
"matchFileNames": [".woodpecker/*.yml"],
|
||||
"addLabels": ["PR Target/Woodpecker-CI"]
|
||||
"matchFileNames": [
|
||||
".woodpecker/*.yml"
|
||||
],
|
||||
"addLabels": [
|
||||
"PR Target/Woodpecker-CI"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
mkdocs-material==9.6.2
|
||||
mkdocs-material==9.6.14
|
||||
mkdocs-glightbox==0.4.0
|
||||
mkdocs-redirects==1.2.2
|
||||
git+https://github.com/Andre601/mkdocs-pagenav-generator
|
||||
mkdocs-macros-plugin==1.3.7
|
||||
mkdocs-macros-plugin==1.3.7
|
||||
pygments-minimessage==1.0.0
|
||||
+3
-3
@@ -97,19 +97,19 @@
|
||||
<dependency>
|
||||
<groupId>com.github.LeonMangler</groupId>
|
||||
<artifactId>PremiumVanishAPI</artifactId>
|
||||
<version>2.9.0-4</version>
|
||||
<version>2.9.18-2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.sayandev</groupId>
|
||||
<artifactId>sayanvanish-api</artifactId>
|
||||
<version>1.6.4</version>
|
||||
<version>1.6.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.sayandev</groupId>
|
||||
<artifactId>sayanvanish-proxy-velocity</artifactId>
|
||||
<version>1.6.4</version>
|
||||
<version>1.6.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -46,19 +46,19 @@
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.13.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.5.16</version>
|
||||
<version>1.5.18</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||
<artifactId>httpclient5</artifactId>
|
||||
<version>5.4.2</version>
|
||||
<version>5.5</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -93,7 +93,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.13.0</version>
|
||||
<version>3.14.0</version>
|
||||
<configuration>
|
||||
<release>16</release>
|
||||
</configuration>
|
||||
|
||||
-2
@@ -26,9 +26,7 @@
|
||||
package ch.andre601.advancedserverlist.versionuploader;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ReleaseHolder{
|
||||
|
||||
|
||||
+35
-8
@@ -53,7 +53,7 @@ public class VersionUploader{
|
||||
|
||||
if(args.length == 0){
|
||||
LOGGER.warn("MISSING ARGUMENT!");
|
||||
LOGGER.warn("COMMAND USAGE: java -jar VersionUploader.jar --all | --modrinth | --hangar [--dryrun]");
|
||||
LOGGER.warn("Usage: java -jar VersionUploader.jar <--help | --all | --modrinth | --hangar> [--dryrun]");
|
||||
System.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -76,15 +76,28 @@ public class VersionUploader{
|
||||
switch(args[0].toLowerCase(Locale.ROOT)){
|
||||
case "--modrinth" -> future = new ModrinthVersionUploader().performUpload(release, releaseHolder, dryrun);
|
||||
case "--hangar" -> future = new HangarVersionUploader().performUpload(release, releaseHolder, dryrun);
|
||||
case "--all" -> {
|
||||
future = CompletableFuture.allOf(
|
||||
new ModrinthVersionUploader().performUpload(release, releaseHolder, dryrun),
|
||||
new HangarVersionUploader().performUpload(release, releaseHolder, dryrun)
|
||||
);
|
||||
case "--all" -> future = CompletableFuture.allOf(
|
||||
new ModrinthVersionUploader().performUpload(release, releaseHolder, dryrun),
|
||||
new HangarVersionUploader().performUpload(release, releaseHolder, dryrun)
|
||||
);
|
||||
case "--help" -> {
|
||||
LOGGER.info("Usage: java -jar VersionUploader.jar <command> [args]");
|
||||
LOGGER.info("");
|
||||
LOGGER.info("Commands:");
|
||||
LOGGER.info(" --help Prints this help page and exits.");
|
||||
LOGGER.info(" --all Performs an upload to all sites.");
|
||||
LOGGER.info(" --modrinth Performs an upload to Modrinth.");
|
||||
LOGGER.info(" --hangar Performs an upload to Hangar.");
|
||||
LOGGER.info("");
|
||||
LOGGER.info("Arguments:");
|
||||
LOGGER.info(" --dryrun Prints the JSON in console while not uploading to any platform.");
|
||||
LOGGER.info("");
|
||||
System.exit(0);
|
||||
return;
|
||||
}
|
||||
default -> {
|
||||
LOGGER.warn("Unknown argument '{}' provided.", args[0]);
|
||||
LOGGER.warn("COMMAND USAGE: java -jar VersionUploader.jar --all | --modrinth | --hangar [--dryrun]");
|
||||
LOGGER.warn("Usage: java -jar VersionUploader.jar <--help | --all | --modrinth | --hangar> [--dryrun]");
|
||||
System.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -125,7 +138,12 @@ public class VersionUploader{
|
||||
"Version `%s` of AdvancedServerList is now available for download on Modrinth and Hangar!",
|
||||
release.tagName()
|
||||
))
|
||||
.setColor(0x1BD96A);
|
||||
.setColor(0x1BD96A)
|
||||
.addField(new WebhookEmbed.EmbedField(
|
||||
false,
|
||||
"Changelog",
|
||||
getDescription(release.body())
|
||||
));
|
||||
|
||||
StringJoiner modrinthText = new StringJoiner("\n");
|
||||
String hangarText = null;
|
||||
@@ -184,4 +202,13 @@ public class VersionUploader{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getDescription(String description){
|
||||
if(description.length() < 1024)
|
||||
return description;
|
||||
|
||||
String temp = description.substring(0, 1014); // Cut it 10 characters shorter than supported.
|
||||
|
||||
return temp.substring(0, temp.lastIndexOf(' ')) + "...";
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -130,7 +130,7 @@ public class HangarVersionUploader{
|
||||
Platform.VELOCITY, velocityDependencies
|
||||
),
|
||||
Map.of(
|
||||
Platform.PAPER, List.of("1.20.x", "1.21.x"),
|
||||
Platform.PAPER, List.of("1.20.6", "1.21.x"),
|
||||
Platform.WATERFALL, List.of("1.19.x", "1.20.x", "1.21"),
|
||||
Platform.VELOCITY, Collections.singletonList("3.2")
|
||||
),
|
||||
|
||||
+16
-13
@@ -40,7 +40,6 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ModrinthVersionUploader{
|
||||
@@ -54,6 +53,10 @@ public class ModrinthVersionUploader{
|
||||
PlatformInfo.BUNGEECORD,
|
||||
PlatformInfo.VELOCITY
|
||||
);
|
||||
private final List<String> paperVersions = List.of(
|
||||
"1.20.6",
|
||||
"1.21", "1.21.1", "1.21.2", "1.21.3", "1.21.4"
|
||||
);
|
||||
private final List<String> versions = List.of(
|
||||
"1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4", "1.20.5", "1.20.6",
|
||||
"1.21", "1.21.1", "1.21.2", "1.21.3", "1.21.4"
|
||||
@@ -100,28 +103,29 @@ public class ModrinthVersionUploader{
|
||||
);
|
||||
|
||||
for(int i = 0; i < platforms.size(); i++){
|
||||
logger.info("Creating release for platform {}...", platforms.get(i).getPlatform());
|
||||
PlatformInfo platformInfo = platforms.get(i);
|
||||
logger.info("Creating release for platform {}...", platformInfo.getPlatform());
|
||||
|
||||
List<File> files = platforms.get(i).getFilePaths().stream()
|
||||
List<File> files = platformInfo.getFilePaths().stream()
|
||||
.map(path -> new File(path.replace("{{version}}", pluginVersion)))
|
||||
.filter(File::exists)
|
||||
.toList();
|
||||
|
||||
CreateVersion.CreateVersionRequest.CreateVersionRequestBuilder builder = CreateVersion.CreateVersionRequest.builder()
|
||||
.projectId("xss83sOY")
|
||||
.name(String.format("v%s (%s)", releaseVersion, String.join(", ", platforms.get(i).getLoaders())))
|
||||
.name(String.format("v%s (%s)", releaseVersion, String.join(", ", platformInfo.getLoaders())))
|
||||
.versionNumber(releaseVersion)
|
||||
.changelog(changelog.replaceAll("\r\n", "\n"))
|
||||
.featured(false)
|
||||
.files(files)
|
||||
.gameVersions(versions)
|
||||
.loaders(platforms.get(i).getLoaders())
|
||||
.gameVersions(platformInfo == PlatformInfo.PAPER ? paperVersions : versions)
|
||||
.loaders(platformInfo.getLoaders())
|
||||
.versionType(prerelease ? ProjectVersion.VersionType.BETA : ProjectVersion.VersionType.RELEASE);
|
||||
|
||||
switch(platforms.get(i).getPlatform().toLowerCase(Locale.ROOT)){
|
||||
case "paper" -> builder.dependencies(paperDependencies);
|
||||
case "bungeecord" -> builder.dependencies(bungeeDependencies);
|
||||
case "velocity" -> builder.dependencies(velocityDependencies);
|
||||
switch(platformInfo){
|
||||
case PAPER -> builder.dependencies(paperDependencies);
|
||||
case BUNGEECORD -> builder.dependencies(bungeeDependencies);
|
||||
case VELOCITY -> builder.dependencies(velocityDependencies);
|
||||
}
|
||||
|
||||
if(dryrun){
|
||||
@@ -134,7 +138,6 @@ public class ModrinthVersionUploader{
|
||||
continue;
|
||||
}
|
||||
|
||||
final int index = i;
|
||||
futures[i] = api.versions().createProjectVersion(builder.build()).whenComplete(((projectVersion, throwable) -> {
|
||||
if(throwable != null){
|
||||
logger.warn("Encountered an exception while uploading a new release to Modrinth!", throwable);
|
||||
@@ -145,11 +148,11 @@ public class ModrinthVersionUploader{
|
||||
|
||||
logger.info("Created new release!");
|
||||
logger.info("Link: {}", url);
|
||||
logger.info("Platform: {}", platforms.get(index).getPlatform());
|
||||
logger.info("Platform: {}", platformInfo.getPlatform());
|
||||
|
||||
releaseHolder.addRelease(
|
||||
"modrinth",
|
||||
String.join(", ", platforms.get(index).getPlatformNames()),
|
||||
String.join(", ", platformInfo.getPlatformNames()),
|
||||
url
|
||||
);
|
||||
}));
|
||||
|
||||
Reference in new issue
Block a user