Compare commits

...
20 Commits
Author SHA1 Message Date
Andre601 0892f5cd1d Use <_ for contains instead of <- 2024-02-03 17:21:54 +01:00
Andre601 452a7e6dcf Merge pull request 'Update dependency mkdocs-material to v9.5.7' (#218) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/218
2024-02-03 12:02:21 +00:00
Andre601's Renovate Bot 162dd10a73 Update dependency mkdocs-material to v9.5.7 2024-02-03 12:01:15 +00:00
Andre601 35120c5364 Bump version to 7.0.0 2024-01-31 21:42:24 +01:00
Andre601 6c828171d2 Add new operands to use 2024-01-31 21:41:22 +01:00
Andre601 dcc51f8458 [Docs] Improve profiles page 2024-01-30 17:32:10 +01:00
Andre601 1287ca62fe Fix platform for ${server host} 2024-01-29 23:24:18 +00:00
Andre601 1ff439fa95 Use Java's HttpClient for update checks 2024-01-29 16:37:49 +01:00
Andre601 ed0f832b2f Merge pull request 'Update dependency mkdocs-material to v9.5.6' (#217) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/217
2024-01-28 12:02:57 +00:00
Andre601's Renovate Bot b8e6b2acc6 Update dependency mkdocs-material to v9.5.6 2024-01-28 12:01:18 +00:00
Andre601 fba32c91c5 Add page about expressions 2024-01-28 00:20:52 +01:00
Andre601 6505ded12b Use assertEquals(...) for testing 2024-01-27 23:25:17 +01:00
Andre601 53088affcb docs/profiles/index.md aktualisiert 2024-01-27 22:23:00 +00:00
Andre601 9c030764fa Merge pull request 'Update dependency mkdocs-glightbox to v0.3.7' (#215) from renovate/mkdocs-glightbox-0.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/215
2024-01-25 12:06:08 +00:00
Andre601 d5d58f1eea Merge branch 'master' into renovate/mkdocs-glightbox-0.x 2024-01-25 12:05:53 +00:00
Andre601 7181092821 Merge pull request 'Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.3.1' (#216) from renovate/org.apache.httpcomponents.client5-httpclient5-5.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/216
2024-01-25 12:05:37 +00:00
Andre601's Renovate Bot fc5ee4f242 Update dependency org.apache.httpcomponents.client5:httpclient5 to v5.3.1 2024-01-25 12:01:04 +00:00
Andre601's Renovate Bot 6e74c4fb14 Update dependency mkdocs-glightbox to v0.3.7 2024-01-25 12:00:59 +00:00
Andre601 f6a27342e6 Merge pull request 'Update dependency mkdocs-material to v9.5.5' (#214) from renovate/mkdocs-material-9.x into master
Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/214
2024-01-24 12:17:57 +00:00
Andre601's Renovate Bot 38b50df2c9 Update dependency mkdocs-material to v9.5.5 2024-01-24 12:00:49 +00:00
20 changed files with 486 additions and 394 deletions

No files matched your search

-10
View File
@@ -108,12 +108,6 @@
<version>4.1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
@@ -149,10 +143,6 @@
<pattern>org.bstats</pattern>
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>okhttp3</pattern>
<shadedPattern>ch.andre601.advancedserverlist.bungeecord.depends.okhttp3</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
@@ -85,6 +85,8 @@ public class BungeeServerPlaceholders extends PlaceholderProvider{
if(args.length == 2){
ServerInfo info = proxy.getServers().get(args[1]);
if(info == null)
yield null;
yield String.valueOf(((InetSocketAddress)info.getSocketAddress()).getHostString());
}
-6
View File
@@ -98,12 +98,6 @@
<version>2.10.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.unascribed</groupId>
<artifactId>flexver-java</artifactId>
@@ -30,18 +30,17 @@ import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import com.unascribed.flexver.FlexVerComparator;
import io.leangen.geantyref.TypeToken;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -49,12 +48,10 @@ import java.util.concurrent.TimeUnit;
public class UpdateChecker{
private final String url = "https://api.modrinth.com/v2/project/advancedserverlist/version?loaders=[\"%s\"]";
private final OkHttpClient client = new OkHttpClient();
private final AdvancedServerList<?> core;
private final PluginLogger logger;
private final String loader;
@SuppressWarnings("FieldCanBeLocal")
// 'https://api.modrinth.com/v2/project/advancedserverlist/version?loaders=["%s"]' URL encoded.
private final String url = "https://api.modrinth.com/v2/project/advancedserverlist/version?loaders=%%5B%%22%s%%22%%5D";
private final HttpClient client = HttpClient.newHttpClient();
private final Type listType = new TypeToken<ArrayList<ModrinthVersion>>(){}.getType();
private final Gson gson = new GsonBuilder()
@@ -65,6 +62,10 @@ public class UpdateChecker{
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new UpdateCheckThread());
private final AdvancedServerList<?> core;
private final PluginLogger logger;
private final String loader;
public UpdateChecker(AdvancedServerList<?> core){
this.core = core;
this.logger = core.getPlugin().getPluginLogger();
@@ -73,12 +74,27 @@ public class UpdateChecker{
startUpdateChecker();
}
public void startUpdateChecker(){
public void disable(){
executor.shutdown();
try{
if(!executor.awaitTermination(1, TimeUnit.SECONDS)){
executor.shutdownNow();
if(!executor.awaitTermination(1, TimeUnit.SECONDS))
logger.warn("Scheduler did not terminate in time!");
}
}catch(InterruptedException ex){
executor.shutdownNow();
Thread.currentThread().interrupt();
}
}
private void startUpdateChecker(){
executor.scheduleAtFixedRate(() -> {
logger.info("Checking for a new update...");
checkUpdate().whenComplete((version, throwable) -> {
logger.info("Looking for an update...");
performUpdateCheck().whenComplete((version, throwable) -> {
if(version == null || throwable != null){
logger.warn("Failed to look for any updates. See previous messages for reasons.");
logger.warn("Failed to look for any updates. Check previous messages for causes.");
return;
}
@@ -87,106 +103,44 @@ public class UpdateChecker{
int result = version.compare(core.getVersion());
switch(result){
case -1 -> printUpdateBanner(version);
case 0 -> logger.info("No new update found. You're running the latest version!");
case 0 -> logger.info("You are running the latest version!");
case 1 -> logger.info(
"Your version (%s) is higher than the latest release (%s). Are you running a dev build?",
core.getVersion(), version.getVersionNumber()
"Your version (%s) seems to be newer than the latest release (%s). Are you running a dev build?",
core.getVersion(), version.versionNumber()
);
}
});
}, 0L, 12L, TimeUnit.HOURS);
}
public void disable(){
executor.shutdown();
client.dispatcher().executorService().shutdown();
try{
if(!executor.awaitTermination(1, TimeUnit.SECONDS)){
executor.shutdownNow();
if(!executor.awaitTermination(1, TimeUnit.SECONDS))
logger.warn("Scheduler didn't terminate in time!");
}
if(!client.dispatcher().executorService().awaitTermination(1, TimeUnit.SECONDS)){
client.dispatcher().executorService().shutdownNow();
if(!client.dispatcher().executorService().awaitTermination(1, TimeUnit.SECONDS))
logger.warn("OkHttp's Scheduler didn't terminate in time!");
}
}catch(InterruptedException ex){
executor.shutdownNow();
Thread.currentThread().interrupt();
private CompletableFuture<ModrinthVersion> performUpdateCheck(){
String finalUrl = String.format(url, loader);
logger.debug(UpdateChecker.class, "Checking '%s' for updates...", finalUrl);
if(core.getVersion().equals("UNKNOWN")){
logger.warn("Cannot perform update check. Plugin version is 'UNKNOWN'!");
return CompletableFuture.completedFuture(null);
}
}
private CompletableFuture<ModrinthVersion> checkUpdate(){
return CompletableFuture.supplyAsync(() -> {
PluginLogger logger = core.getPlugin().getPluginLogger();
String finalUrl = String.format(url, loader);
logger.debug(UpdateChecker.class, "Looking for updates on '%s'...", finalUrl);
if(core.getVersion().equals("UNKNOWN")){
logger.warn("Cannot perform Update check! Plugin version couldn't be parsed.");
return null;
}
Request request = new Request.Builder()
.url(finalUrl)
HttpRequest request;
try{
request = HttpRequest.newBuilder()
.uri(new URI(finalUrl))
.header("User-Agent", "AdvancedServerList-" + loader + "/" + core.getVersion())
.build();
logger.debug(UpdateChecker.class, "Connecting to website...");
try(Response response = client.newCall(request).execute()){
logger.debug(UpdateChecker.class, "Connected! Checking response code...");
if(!response.isSuccessful()){
logger.warn("Encountered a non-successful response from Modrinth! Code: %d", response.code());
return null;
}
logger.debug(UpdateChecker.class, "Received positive response code '%d'", response.code());
ResponseBody body = response.body();
if(body == null){
logger.warn("Received an empty Response body from Modrinth!");
return null;
}
String responseString = body.string();
if(responseString.isEmpty()){
logger.warn("Received an empty Response body from Modrinth!");
return null;
}
logger.debug(UpdateChecker.class, "Received non-empty response body. Parsing it from JSON Array...");
List<ModrinthVersion> list = gson.fromJson(responseString, listType);
if(list == null || list.isEmpty()){
logger.warn("Couldn't convert JSON Array into a valid list.");
return null;
}
ModrinthVersion version = list.get(0);
logger.debug(UpdateChecker.class, "Found entry '%s'", version);
if(version.getVersionNumber() == null || version.getVersionNumber().isEmpty()){
logger.warn("Cannot check latest version. Received version number was null/empty.");
return null;
}
logger.debug(UpdateChecker.class, "Successfully parsed version!");
return version;
}catch(JsonSyntaxException ex){
logger.warn("Encountered invalid JSON from Response body!", ex);
}catch(URISyntaxException ex){
logger.warn("Cannot perform update check. URL '%s' is not a valid URI.", ex, finalUrl);
return CompletableFuture.completedFuture(null);
}
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8))
.thenApply(response -> new ArrayList<ModrinthVersion>(gson.fromJson(response.body(), listType)))
.thenApply(list -> list.get(0))
.exceptionally((throwable) -> {
logger.warn("Encountered exception while performing update check!", throwable);
return null;
}catch(IOException ex){
logger.warn("Encountered Exception while checking for an update!", ex);
return null;
}
});
});
}
private void printUpdateBanner(ModrinthVersion version){
@@ -194,53 +148,33 @@ public class UpdateChecker{
logger.info("You are running an outdated version of AdvancedServerList!");
logger.info("");
logger.info("Your version: %s", core.getVersion());
logger.info("Modrinth version: %s", version.getVersionNumber());
logger.info("Modrinth: %s", version.versionNumber());
logger.info("");
if(!version.isRelease()){
logger.info("WARNING: This release is an Alpha/Beta! It may contain");
logger.info(" breaking changes!");
logger.info("WARNING!");
logger.info("This is a %s version and may contain breaking changes and/or bugs!", version.versionType());
logger.info("");
}
logger.info("You can download the latest release from here:");
logger.info("https://modrinth.com/plugin/advancedserverlist/version/%s", version.getId());
logger.info("Download the latest version from here:");
logger.info("https://modrinth.com/plugin/advancedserverlist/version/%s", version.id());
logger.info("==================================================================");
}
public static class ModrinthVersion{
@SuppressWarnings("FieldMayBeFinal")
private String id;
@SuppressWarnings("FieldMayBeFinal")
private String versionNumber;
@SuppressWarnings("FieldMayBeFinal")
private String versionType;
public ModrinthVersion(String id, String versionNumber, String versionType){
this.id = id;
this.versionNumber = versionNumber;
this.versionType = versionType;
}
public String getId(){
return id;
}
public String getVersionNumber(){
return versionNumber;
}
public record ModrinthVersion(String id, String versionNumber, String versionType){
public boolean isRelease(){
return versionType.equals("release");
return versionType().equals("release");
}
public int compare(String version){
return FlexVerComparator.compare(version, versionNumber);
return FlexVerComparator.compare(version, versionNumber());
}
@Override
public String toString(){
return String.format("ModrinthVersion{id=%s,versionNumber=%s,versionType=%s}", id, versionNumber, versionNumber);
return String.format("ModrinthVersion{id=%s,versionNumber=%s,versionType=%s}", id, versionNumber, versionType);
}
}
}
@@ -98,6 +98,9 @@ public class ExpressionEngine{
.tokenReader(new PatternTokenReader(DefaultTokens.NOT_EQUAL, "!="))
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL_IGNORE_CASE, "~="))
.tokenReader(new PatternTokenReader(DefaultTokens.NOT_EQUAL_IGNORE_CASE, "!~"))
.tokenReader(new PatternTokenReader(DefaultTokens.STARTS_WITH, "|-"))
.tokenReader(new PatternTokenReader(DefaultTokens.ENDS_WITH, "-|"))
.tokenReader(new PatternTokenReader(DefaultTokens.CONTAINS, "<_"))
.tokenReader(new PatternTokenReader(DefaultTokens.GREATER_OR_EQUAL_THAN, ">="))
.tokenReader(new PatternTokenReader(DefaultTokens.LESSER_OR_EQUAL_THAN, "<="))
.tokenReader(new PatternTokenReader(DefaultTokens.OPENING_PARENTHESIS, "("))
@@ -125,6 +128,9 @@ public class ExpressionEngine{
.operator(DefaultTokens.NOT_EQUAL, Operator.of(25, ExpressionTemplates::notEqual))
.operator(DefaultTokens.EQUAL_IGNORE_CASE, Operator.of(25, ExpressionTemplates::equalIgnoreCase))
.operator(DefaultTokens.NOT_EQUAL_IGNORE_CASE, Operator.of(25, ExpressionTemplates::notEqualIgnoreCase))
.operator(DefaultTokens.STARTS_WITH, Operator.of(25, ExpressionTemplates::startsWith))
.operator(DefaultTokens.ENDS_WITH, Operator.of(25, ExpressionTemplates::endsWith))
.operator(DefaultTokens.CONTAINS, Operator.of(25, ExpressionTemplates::contains))
.operator(DefaultTokens.GREATER_THAN, Operator.of(25, ExpressionTemplates::greater))
.operator(DefaultTokens.GREATER_OR_EQUAL_THAN, Operator.of(25, ExpressionTemplates::greaterOrEqual))
.operator(DefaultTokens.LESSER_THAN, Operator.of(25, ExpressionTemplates::less))
@@ -32,7 +32,7 @@ import java.util.Collection;
public class Expressions{
public static ToBooleanExpression negate(ToBooleanExpression expression){
return new AbstractUnaryToBooleanExpression<>(expression) {
return new AbstractUnaryToBooleanExpression<>(expression){
@Override
public boolean evaluate(){
return !delegate.evaluate();
@@ -41,7 +41,7 @@ public class Expressions{
}
public static ToBooleanExpression and(Collection<ToBooleanExpression> operands){
return new AbstractToBooleanExpression<>(operands) {
return new AbstractToBooleanExpression<>(operands){
@Override
public boolean evaluate(){
for(ToBooleanExpression operand : operands){
@@ -55,7 +55,7 @@ public class Expressions{
}
public static ToBooleanExpression or(Collection<ToBooleanExpression> operands){
return new AbstractToBooleanExpression<>(operands) {
return new AbstractToBooleanExpression<>(operands){
@Override
public boolean evaluate(){
for(ToBooleanExpression operand : operands){
@@ -69,7 +69,7 @@ public class Expressions{
}
public static ToStringExpression concat(Collection<ToStringExpression> operands){
return new AbstractToStringExpression<>(operands) {
return new AbstractToStringExpression<>(operands){
@Override
public String evaluate(){
StringBuilder result = new StringBuilder();
@@ -83,7 +83,7 @@ public class Expressions{
}
public static ToBooleanExpression equal(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate().equals(b.evaluate());
@@ -92,7 +92,7 @@ public class Expressions{
}
public static ToBooleanExpression notEqual(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return !a.evaluate().equals(b.evaluate());
@@ -101,7 +101,7 @@ public class Expressions{
}
public static ToBooleanExpression equalIgnoreCase(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate().equalsIgnoreCase(b.evaluate());
@@ -110,7 +110,7 @@ public class Expressions{
}
public static ToBooleanExpression notEqualIgnoreCase(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return !a.evaluate().equalsIgnoreCase(b.evaluate());
@@ -118,8 +118,35 @@ public class Expressions{
};
}
public static ToBooleanExpression startsWith(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate().startsWith(b.evaluate());
}
};
}
public static ToBooleanExpression endsWith(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate().endsWith(b.evaluate());
}
};
}
public static ToBooleanExpression contains(ToStringExpression a, ToStringExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate().contains(b.evaluate());
}
};
}
public static ToBooleanExpression greaterThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate() > b.evaluate();
@@ -128,7 +155,7 @@ public class Expressions{
}
public static ToBooleanExpression greaterOrEqualThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate() >= b.evaluate();
@@ -137,7 +164,7 @@ public class Expressions{
}
public static ToBooleanExpression lessThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate() < b.evaluate();
@@ -146,7 +173,7 @@ public class Expressions{
}
public static ToBooleanExpression lessOrEqualThan(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToBooleanExpression<>(a, b) {
return new AbstractBinaryToBooleanExpression<>(a, b){
@Override
public boolean evaluate(){
return a.evaluate() <= b.evaluate();
@@ -155,7 +182,7 @@ public class Expressions{
}
public static ToDoubleExpression sum(Collection<ToDoubleExpression> operands){
return new AbstractToDoubleExpression<>(operands) {
return new AbstractToDoubleExpression<>(operands){
@Override
public double evaluate(){
double result = 0;
@@ -169,7 +196,7 @@ public class Expressions{
}
public static ToDoubleExpression product(Collection<ToDoubleExpression> operands){
return new AbstractToDoubleExpression<>(operands) {
return new AbstractToDoubleExpression<>(operands){
@Override
public double evaluate(){
double result = 1;
@@ -183,7 +210,7 @@ public class Expressions{
}
public static ToDoubleExpression sub(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToDoubleExpression<>(a, b) {
return new AbstractBinaryToDoubleExpression<>(a, b){
@Override
public double evaluate(){
return a.evaluate() - b.evaluate();
@@ -192,7 +219,7 @@ public class Expressions{
}
public static ToDoubleExpression div(ToDoubleExpression a, ToDoubleExpression b){
return new AbstractBinaryToDoubleExpression<>(a, b) {
return new AbstractBinaryToDoubleExpression<>(a, b){
@Override
public double evaluate(){
return a.evaluate() / b.evaluate();
@@ -201,7 +228,7 @@ public class Expressions{
}
public static ToDoubleExpression negateNumber(ToDoubleExpression a){
return new AbstractUnaryToDoubleExpression<>(a) {
return new AbstractUnaryToDoubleExpression<>(a){
@Override
public double evaluate(){
return -delegate.evaluate();
@@ -66,6 +66,18 @@ public class ExpressionTemplates{
return new NotEqualIgnoreCase(a, b);
}
public static ExpressionTemplate startsWith(ExpressionTemplate a, ExpressionTemplate b){
return new StartsWith(a, b);
}
public static ExpressionTemplate endsWith(ExpressionTemplate a, ExpressionTemplate b){
return new EndsWith(a, b);
}
public static ExpressionTemplate contains(ExpressionTemplate a, ExpressionTemplate b){
return new Contains(a, b);
}
public static ExpressionTemplate greater(ExpressionTemplate a, ExpressionTemplate b){
return new Greater(a, b);
}
@@ -222,6 +234,54 @@ public class ExpressionTemplates{
}
}
private static class StartsWith extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
private StartsWith(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.startsWith(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class EndsWith extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
private EndsWith(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.endsWith(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class Contains extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
private final ExpressionTemplate b;
private Contains(ExpressionTemplate a, ExpressionTemplate b){
this.a = a;
this.b = b;
}
@Override
public ToBooleanExpression instantiateWithBooleanResult(){
return Expressions.contains(a.instantiateWithStringResult(), b.instantiateWithStringResult());
}
}
private static class Greater extends AbstractBooleanExpressionTemplate{
private final ExpressionTemplate a;
@@ -34,6 +34,9 @@ public class DefaultTokens{
public static final Token NOT_EQUAL = new Token("NOT_EQUAL");
public static final Token EQUAL_IGNORE_CASE = new Token("EQUAL_IGNORE_CASE");
public static final Token NOT_EQUAL_IGNORE_CASE = new Token("NOT_EQUAL_IGNORE_CASE");
public static final Token STARTS_WITH = new Token("STARTS_WITH");
public static final Token ENDS_WITH = new Token("ENDS_WITH");
public static final Token CONTAINS = new Token("CONTAINS");
public static final Token NEGATION = new Token("NEGATION");
public static final Token GREATER_THAN = new Token("GREATER_THAN");
public static final Token GREATER_OR_EQUAL_THAN = new Token("GREATER_OR_EQUAL_THAN");
@@ -30,6 +30,8 @@ import org.junit.jupiter.api.Test;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ExpressionParserTests{
private final ExpressionEngine expressionEngine = new ExpressionEngine();
@@ -43,6 +45,7 @@ public class ExpressionParserTests{
boolean result = expressionEngine.compile(values.getKey(), logger, null, null).instantiateWithBooleanResult().evaluate();
logger.info("Result (output, isExpected): " + result + ", " + (result == values.getValue()));
assertEquals(result, values.getValue());
}
}
@@ -2,7 +2,7 @@
icon: octicons/arrow-right-24
---
# < 3.7.0 to 3.7.0
# < v3.7.0 to v3.7.0
Version 3.7.0 of AdvancedServerList brought significant changes to its conditions system.
Namely, the `conditions` option is now deprecated and planned for removal in a future release of the Plugin, and the new [`condition`](../profiles/index.md#condition) option should now be used instead.
+50
View File
@@ -0,0 +1,50 @@
---
icon: octicons/arrow-right-24
---
# v3.7.0 to v3.8.0
v3.8.0 brought a small yet important change to the condition system, which is the change of the "contains" operand from `<-` to `<_` to avoid possible issues with numbers.
## Migration
To migrate, switch any appearances of `<-` with `<_`
## Example
Here is a before and after example to help visualize the change:
/// tab | Before
```yaml
priority: 0
conditions: '${server host} <- "survival"'
motd:
- 'Welcome ${player name}!'
```
///
/// tab | After
```yaml
priority: 0
# The text can all be in one line. This is only for better readability.
condition: '${server host} <_ "survival"'
motd:
- 'Welcome ${player name}!'
```
///
/// tab | Diff View
```diff
priority: 0
-condition: '${server host} <- "survival"'
+condition: '${server host} <_ "survival"'
motd:
- 'Welcome ${player name}!'
```
///
+123
View File
@@ -0,0 +1,123 @@
---
icon: octicons/file-code-24
---
Expressions are part of a Server List Profile's condition system and allows you to define when a profile should and should not be displayed.
This page covers what the Expression system of AdvancedServerList offers and can do.
## Content
- [Types](#types)
- [Literals](#literals)
- [Numbers](#numbers)
- [Strings](#strings)
- [Booleans](#booleans)
- [Placeholders](#placeholders)
- [Binary Operators](#binary-operators)
- [Parenthesis](#parenthesis)
- [Negation](#negation)
- [Credits](#credits)
## Types
An expression contains different types of components that are evaluated to return a boolean output of either `true` or `false`.
Depending on the type(s) will the output be differently understood and handled.
### Literals
The following cases are considered literal values:
#### Numbers
Any number is considered an expression, meaning the below examples are considered valid:
```
0
1000
-7
47.2
```
#### Strings
A String in single or double quotes is a valid expression.
/// warning | Important
Specific keywords will be treated as [Binary Operators](#binary-operators) even if they are part of a word.
As an example, `Sand` would cause the expression engine to see `S AND` due to parts of the word matching `and`.
To avoid this is it very important to always surround Strings with single or double quotes, as that tells the expression engine to treat as a String.
///
```
"Hello World!"
""
```
#### Booleans
Strings `true` and `false` are treated as boolean literals.
### Placeholders
Any [placeholder](placeholders.md) is a valid expression.
```
${player protocol}
${player name}
${server playersOnline}
${server host}
```
### Binary Operators
`<expression> <binary operator> <expression>` is a valid expression.
The following binary operators can be used for boolean evaluation:
| Operator | True if |
|----------------------------------|-------------------------------------------------------------------------------------------------------------|
| `and` / `&&` | Both expressions return true. |
| `or` / <code>&#124;&#124;</code> | Either expression returns true. |
| `==` / `=` | Both expressions are equal (Case sensitive). |
| `~=` | Both expressions are equal (Not Case sensitive). |
| `!=` | Both expressions are not equal (Case sensitive). |
| `!~` | Both expressions are not equal (Not case sensitive). |
| <code>&#124;-</code> | Left expression starts with right expression. |
| <code>-&#124;</code> | Left expression ends with right expression. |
| `<-` | Left expression contains right expression. |
| `<` | Left expression is less than the right expression. Strings use their text length as number. |
| `<=` | Left expression is less than, or equal to, the right expression. Strings use their text length as number. |
| `>` | Left expression is larger than the right expression. Strings use their text length as number. |
| `>=` | Left expression is larger than, or equal to, the right expression. Strings use their text length as number. |
Additionally can these additional binary operators used for specific actions:
| Operator | Semantic |
|----------|-----------------------------------------------------------------------------|
| `.` | Concatenates (merges) two Strings |
| `+` | Adds two numbers. Strings use their text length as number. |
| `-` | Subtracts one number from another. Strings use their text length as number. |
| `*` | Multiplies two numbers. Strings use their text length as number. |
| `/` | Divides one number by another. Strings use their text length as number. |
### Parenthesis
`( <expression> )` is a valid expression.
Parenthesis can be used to prevent ambiguities.
### Negation
`!` can be used to negate boolean expressions.
```
!${player isWhitelisted}
```
## Credits
This page, including examples used, was adobted from the BungeeTabListPlus wiki.
The original wiki page can be found here: https://github.com/CodeCrafter47/BungeeTabListPlus/wiki/Expressions
+109 -138
View File
@@ -2,115 +2,77 @@
icon: octicons/note-24
---
# Profiles { #profiles-settings }
# Profiles { #profiles-file }
AdvancedServerList allows the creation of multiple profiles.
A profile is a single YAML file located in the plugin's `profiles` directory containing multiple settings including [Conditions](#conditions) and [Priority](#priority).
AdvancedServerList allows you to create multiple so called Server List Profiles.
A Server List Profile is a YAML file located in the plugin's `profiles` folder. Each Server List Profile allows you to modify one or multiple aspects of your server's display in a Multiplayer Server list.
/// info | Important
In order for a profile to be considered "valid" by AdvancedServerList will it need to meet the following conditions:
Additionally can [Conditions](#condition) and a [Priority](#priority) be set to set when a specific profile should be displayed to a player.
- Have a [`Priority`](#priority) set to a valid, whole number (i.e. `1`)
- Have **at least one** of the following options set:
- [`Profiles`](#profiles) with at least one entry containing one of the below option
- [`Motd`](#motd) set with at least one line of text
- [`Favicon`](#favicon) set with a non-empty String
- [`HidePlayers`](#hideplayers) set to `true`
- [`Hover`](#hover) set with at least one line of text
- [`Text`](#text) set with a non-empty String
///
## Required Options
For a Server List Profile to be valid, will it require the following options to be set:
- A valid [`priority`](#priority) option with a single, whole number.
- **At least** one of the following options:
- [`profiles`](#profiles) with at least one of the below options set.
- [`motd`](#motd) with at least one line to display.
- [`favicon`](#favicon) with a non-empty String.
- [`playerCount -> hidePlayers`](#hideplayers) with value `true`.
- [`playerCount -> hover`](#hover) with at least one line to display.
- [`playerCount -> text`](#text) with a non-empty String.
## Priority
The priority option determines the order in which the profiles are checked by AdvancedServerList, starting with the highest number.
The Priority option allows you to define what Server List Profile should be chosen first.
The plugin will go highest value to lowest value and will select the first Profile that has a [`condition`](#condition) returning `true`.
It will go through each file until it finds one with [`condition`](#condition) returning true (Default if no conditions are set).
This means that a profile with no conditions and a priority of `1` will be used before a profile with a condition and priority `0` even if the player is meeting the condition.
Should AdvancedServerList not find any profile with a positive condition will it not modify the server list for the players.
/// 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
<!-- admo:tip Surround any text that is not an operand or placeholder in single or double quotes to avoid parsing errors. -->
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.
A string containing one or multiple conditions chained together using the keywords `and` or `or` (Or alternatively `&&` or `||`).
The system used for conditions is adobted from BungeeTabListPlus.
The condition option can hold one or multiple expressions. The Expression system is explained on the [Expressions page](expressions.md).
/// details | Example
type: example
## Conditions :octicons-trash-24:{ style="color: #FF5252;" title="Deprecated" }
```yaml title="YAML file"
priority: 0
<!-- admo:deprecated Deprecated in favour of the new condition option. Will be removed in a future version. -->
# Checks if the player is using 1.20 or newer AND is whitelisted
condition: |
${player protocol} >= 763 and
${player isWhitelisted}
The `conditions` option - not to be confused with the new [`condition`](#condition) option - allows you to define one or multiple conditions/expressions that all need to return `true` in order for the profile to be used.
Not setting this option, or setting it to an empty list (`conditions: []`), will result in `true` being returned.
motd:
- 'Welcome ${player name}!'
```
///
Each condition can use [placeholders](placeholders.md) to further customize it. PlaceholderAPI placeholders are **not** supported!
### Operands { #condition-operands }
### Operands
The following operands can be used for expressions in the condition option.
<!-- admo:warning Each condition can only hold one operand -->
| Operand | Description |
|--------------|------------------------------------------------------------------------------------------------------------------|
| `and` / `&&` | Returns true if the expression on the left and right side return true. |
| `or` / `||` | Returns true if an expression from either side returns true. |
| `()` | Expressions in-between those are prioritized in evaluation, starting with the most inner first. |
| `<` | Returns true if the left side is less than the right. In case of text will the text length be used. |
| `<=` | Returns true if the left side is less or equal to the right. In case of text will the text length be used. |
| `>` | Returns true if the left side is larger than the right. In case of text will the text length be used. |
| `>=` | Returns true if the left side is larger or equal to the right. In case of text will the text length be used. |
| `==` / `=` | Returns true if both sides are equal to each other. This also checks capitalization. |
| `!=` | Returns true if both sides are NOT equal to each other. This also checks capitalization. |
| `~=` | Returns true if both sides are equal to each other while also ignoring capitalization. |
| `!~` | Returns true if both sides are NOT equal to each other while also ignoring capitalization. |
| `.` | Merges two strings into one. |
| `+` | Adds two numbers together. In case of text will its text length be used as number. |
| `-` | Subtracts the value from the right from the left number. In case of text will its text length be used as number. |
| `*` | Multiplies two numbers together. In case of text will its text length be used as number. |
| `/` | Divides the left number through the right number. In case of text will its text length be used as number. |
Each condition can use operands to compare values with each other.
Note that if Operands are used that compare sizes (i.e. `>`) while the values are Text and not numbers will the text length be used as number.
## Conditions :octicons-trash-24:{ title="Deprecated" style="color: #ff5252;" }
<!-- admo:deprecated This option was deprecated in favour of the new condition option! -->
A list of conditions can be set that need to be met in order to have this profile shown to the player.
[Placeholders](formatting.md#placeholders) can be used to further customize the conditions (PlaceholderAPI placeholders are **not** supported).
Only when **all** conditions defined return true will the profile be displayed.
You can remove this option, or set it to an empty list (`conditions: []`) to always return true.
### Operands { #conditions-operands }
The following operants are available and can be used in the conditions.
<!-- admo:warning For conditions option can you only use one operand per condition. -->
| Operand | Description |
|---------------|-------------------------------------------------------------------------|
| `<` | Checks if the left value is less than the right one.[^1] |
| `<=` | Checks if the left value is less than or equal to the right one.[^1] |
| `>` | Checks if the left value is more than the right one.[^1] |
| `>=` | Checks if the left value is more than or equal to the right one.[^1] |
| `=` | Checks if the left value is equal to the right one. |
| `!=` | Checks if the left value is not equal to the right one. |
| `~=` | Checks if the left value is equal to the right one, ignoring case. |
| `!~` | Checks if the left value is not equal to the right one, ignoring case. |
[^1]:
Should the provided value not be a number, will AdvancedServerList use the text length to compare.
Example: `SomeString > String` would be translated to `10 > 6`.
| Operand | What it does |
|---------|----------------------------------------------------------------------------|
| `<` | Returns true if the left value is less than the right value. |
| `<=` | Returns true if the left value is less than, or equal to, the right value. |
| `>` | Returns true if the left value is more than the right value. |
| `>=` | Returns true if the left value is less than, or equal to, the right value. |
| `=` | Returns true if both values are equal (Case sensitive). |
| `!=` | Returns true if both values are not equal (Case sensitive). |
| `~=` | Returns true if both values are equal (Not case sensitive). |
| `!~` | Returns true if both values are not equal (Not case sensitive). |
## Profiles
<!-- admo:warning Priority and Conditions can NOT be used within profiles -->
The `profile` option allows you to define a list of all other options, with the exception of [`priority`](#priority), [`condition`](#condition) or itself.
The `profiles` option allows you to set multiple MOTDs, player counts, etc. which the plugin would randomly choose from.
If an option such as motd is not present in an entry will it check the file for the option and use that if present.
When multiple entries are defined will AdvancedServerList randomly select one.
Should an option exist in the file itself (i.e. [`motd`](#motd)) but not in the selected profiles entry will it be used. This allows you to randomize only one aspect of a Server List Profile while keeping all other options the same.
/// details | Example
type: example
@@ -119,7 +81,7 @@ If an option such as motd is not present in an entry will it check the file for
priority: 0
profiles:
- motd:
- motd: # You can also use ['<rainbow>Line1</rainbow>','<rainbow:!>Line 2</rainbow>']
- '<rainbow>Line 1</rainbow>'
- '<rainbow:!>Line 2</rainbow>'
playerCount:
@@ -127,6 +89,7 @@ profiles:
- 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>'
@@ -141,10 +104,10 @@ motd:
## Motd
The motd option allows to set up to two lines to be displayed in an MOTD.
Normal colour and formatting codes such as `<aqua>` or `<bold>` are supported. On 1.16 and newer can you also use HEX colours using either `<#rrggbb>` or `<color:#rrggbb>`.
The `motd` option allows you to alter the "Message of the day" that is being displayed on a server in the multiplayer screen.
Please see the [Formatting](formatting.md) for all supported formatting options.
If you want to display multiple MOTDs will you need to use the [`Profiles` option](#profiles)
Multiple, randomly selected, MOTDs can be displayed by using the [`profiles`](#profiles) option.
/// details | Example
type: example
@@ -153,7 +116,7 @@ If you want to display multiple MOTDs will you need to use the [`Profiles` optio
priority: 0
motd:
- '<rainbow:2>Rainbow Gradients</rainbow>'
- '<rainbow:2>Rainbow Gradient</rainbow>'
- '<rainbow:!2>|||||||||||||||||||||||||||||||||||||</rainbow>'
```
<div class="result" markdown>
@@ -165,53 +128,60 @@ motd:
## Favicon
The favicon option allows you to customize the favicon and display one or multiple different images.
<!-- admo:info Images will be resized to 64x64 pixels. -->
This option currently supports the following values:
The `favicon` option can be used to define an image to display in the server list.
- A URL pointing to a `64x64` PNG image.
- A name with `.png` extension that matches a PNG file in the `favicons` folder.
- `${player uuid}` (or alternatively `${player name}`) to display the head of the player. The UUID/Name resolving is handled by https://mc-heads.net
The Value can be one of three possible options, each being checked for in order:
Please note that AdvancedServerList will rescale the image to be 64x64 pixels, so be sure to provide images at that particular scale.
- A URL pointing to an image file. The URL needs to start with `https://` to work.
- A PNG filename, including `.png` file extension, matching a PNG file in the `favicons` folder.
- A player name or UUID, or a [placeholder](placeholders.md) that resolves into one.
Note that for the name/UUID, the site https://mc-heads.net is being used.
Use the URL option with the `${player uuid}` placeholder if you want to use another service.
/// details | Example
type: example
```yaml title="YAML file"
priority: 0
# We use just colour to hide the MOTD
# Hides the MOTD for demonstration purposes
motd:
- '<grey>'
- '<grey>'
# Player is Andre_601
favicon: ${player uuid}
# Placeholder resolves to UUID of Andre_601
favicon: '${player uuid}'
```
<div class="result" markdown>
![hideplayers-example](../assets/images/examples/favicon-example.jpg){ loading="lazy" }
![favicon-example](../assets/images/examples/favicon-example.jpg){ loading="lazy" }
</div>
///
## PlayerCount
The `playerCount` option contains multiple different options all about the Player count itself.
The `playerCount` option contains various other options that are used to modify the player count (The text next to the ping icon that shows the online and max players of a server).
### HidePlayers
Boolean option to set whether AdvancedServerList should hide the player count or not. When set to `true` will the player count be replaced with `???`.
Additionally will the [`Text`](#text) and [`Hover`](#hover) option be ignored.
The `playerCount -> hidePlayers` option takes a boolean (`true` or `false`) to set whether the player count should be hidden or not.
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
# We use just colour to hide the MOTD
# Hides the MOTD for demonstration purposes
motd:
- '<grey>'
- '<grey>'
@@ -228,17 +198,17 @@ playerCount:
### Hover
This option allows to override the hover text usually displaying the players on the server when hovering over the player count.
You can either remove this option or set to an empty list (`hover: []`) to not override the 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.
Note that this option only accepts basic colors such as `<blue>` or `<grey>` and that HEX colors are not supported.
/// details | Example
type: example
```yaml title="YAML file"
priority: 0
# We use just colour to hide the MOTD
# Hides the MOTD for demonstration purposes
motd:
- '<grey>'
- '<grey>'
@@ -258,23 +228,24 @@ playerCount:
### Text
This option allows to override the text usually displaying the online players and total players that can join.
Note that AdvancedServerList will not add the `<online>/<max>` text to the player count. Instead will you need to use [`${server playersOnline}`](placeholders.md#server) and [`${server playersMax}`](placeholders.md#server)
The `playerCount -> text` option allows you to define a custom text to display instead of the usual `<online>/<max>`.
/// info | Note
This feature works by changing the "outdated server" message followed by altering the protocol version of the server.
Due to this will your server appear as "outdated" to the client (Have the ping icon crossed out). This is nothing that can be changed unfortunately.
///
Please take note of the following caveats:
To not override the player count, remove this option or set it to an empty String (`text: ''`).
- The plugin won't automatically add the `<online>/<max>` back to the text you set. Instead you'll have to use `${server playersOnline}/${server playersMax}` to recreate this.
- The override is done by using the "outdated server" text displayed when a client pings a server that is not compatible. This means that the ping icon will appear crossed out and your server will be seen as "outdated" by the client (When hovering over the ping icon). This can't be avoided nor fixed by the plugin.
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
# We use just colour to hide the MOTD
# Hides the MOTD for demonstration purposes
motd:
- '<grey>'
- '<grey>'
@@ -284,35 +255,37 @@ playerCount:
```
<div class="result" markdown>
![hover-example](../assets/images/examples/text-example.jpg){ loading="lazy" }
![text-example](../assets/images/examples/text-example.jpg){ loading="lazy" }
</div>
///
### ExtraPlayers
Contains options to modify how the `<max>` number in the player count should look like.
<!-- admo:warning Using this option overrides the output of the <code>${server playersMax}</code> placeholder (Except in condition). -->
<!-- admo:warning Using this option will modify the <code>${server playersMax}</code> placeholder (Except when used in conditions) -->
The `playerCount -> extraPlayers` option contains settings for the "extra players" feature, which adds X to the current online player count and sets it as the server's max player count.
#### Enabled { #extraplayers-enabled }
Boolean option to set whether the extra players feature should be used or not.
When set to `true` will the max amount of players be modified by taking the current amount of online players, add [`Amount`](#amount) more to it and use it.
Enables the extraPlayers feature.
Use the [`playerCount -> extraPlayers -> amount`](#extraplayers-amount) option to set how much to add to the max players count.
#### Amount { #extraplayers-amount }
Sets the number to add to the current online players to then use as the new max players count.
<!-- admo:info This option does nothing when <code>playerCount -> hidePlayers</code> is enabled. -->
As an example, setting this to `1` while `10` players are online will display `11`, while `-1` would display `9`.
The `playerCount -> extraPlayers -> amount` option defines how much should be added to the current online player count to then use as max player count.
Example: Setting this option to `1` while currently 10 players are online will result in `10/11` being displayed on the player count (Assuming it is not being overriden by the [`playerCount -> text`](#text) option).
/// details | Example
type: example
```yaml title="YAML file"
priority: 0
# We use just colour to hide the MOTD
# Hides the MOTD for demonstration purposes
motd:
- '<grey>'
- '<grey>'
@@ -331,32 +304,30 @@ playerCount:
### MaxPlayers
Contains options to set the max number of players allowed to join the server. This has only a visual effect and won't actually influence how many players can join your server.
<!-- admo:info This feature is ignored should <code>playerCount -> extraPlayers</code> be enabled. -->
<!-- admo:warning Using this option overrides the output of the <code>${server playersMax}</code> placeholder (Except in condition). -->
Note that this feature is ignored should [`extraPlayers`](#extraplayers) be enabled.
In case [`hidePlayers`](#hideplayers) is enabled will the max player count not be displayed, but still changed by this option.
Should [`text`](#text) be set to a non-empty String will the max player count only be displayed when `${server playersMax}` is used.
<!-- admo:warning Using this option will modify the <code>${server playersMax}</code> placeholder (Except when used in conditions) -->
The `playerCount -> maxPlayers` option is similar in nature to the [`playerCount -> extraPlayers`](#extraplayers) option, with the difference that the number set is being used as the max player count, instead of adding it together with the online player count first.
#### Enabled { #maxplayers-enabled }
Boolean option to set whether the max players feature should be used or not.
When set to `true` will the value usually displaying how many players can join be changed to what you've set in the [`amount`](#maxplayers-amount) option.
Enables the maxPlayers feature.
Use the [`playerCount -> maxPlayers -> amount`](#maxplayers-amount) option to set the max player count itself.
#### Amount { #maxplayers-amount }
Sets the number to display as the max number of players allowed to join your server.
Note that this will also affect the `${server playersMax}` placeholder, except when it is used inside conditions.
<!-- admo:info This option does nothing when <code>playerCount -> hidePlayers</code> is enabled. -->
The `playerCount -> maxPlayers -> amount` option defines the number to use as the server's max players count.
Unlike the [`playerCount -> extraPlayers -> amount`](#extraplayers-amount) option does this one not first add the current online player count to the number to then set.
/// details | Example
type: example
```yaml title="YAML file"
priority: 0
# We use just colour to hide the MOTD
# Hides the MOTD for demonstration purposes
motd:
- '<grey>'
- '<grey>'
@@ -368,7 +339,7 @@ playerCount:
```
<div class="result" markdown>
![maxplayes-example](../assets/images/examples/maxplayers-example.jpg){ loading="lazy" }
![maxplayers-example](../assets/images/examples/maxplayers-example.jpg){ loading="lazy" }
</div>
///
+12 -12
View File
@@ -21,9 +21,9 @@ These placeholders use the player who pinged the server, to return values. They
| `${player protocol}` | The protocol version of the player. | All | No |
| `${player uuid}` | The UUID of the player. | All | Yes[^3] |
| `${player version}` | The protocol version of the player as readable MC version. | Velocity | No |
| `${player hasPlayedBefore}` | Boolean for whether the player has played on the server before. | Spigot/Paper | Yes |
| `${player isBanned}` | Boolean for whether the player has been banned from the server. | Spigot/Paper | Yes |
| `${player isWhitelisted}` | Boolean for whether the player is whitelisted on the server. | Spigot/Paper | Yes |
| `${player hasPlayedBefore}` | Boolean for whether the player has played on the server before. | Paper | Yes |
| `${player isBanned}` | Boolean for whether the player has been banned from the server. | Paper | Yes |
| `${player isWhitelisted}` | Boolean for whether the player is whitelisted on the server. | Paper | Yes |
[^1]:
Whether this placeholder requires the player to have joined before while AdvancedServerList was running.
@@ -35,21 +35,21 @@ These placeholders use the player who pinged the server, to return values. They
These placeholders use values given by the server/proxy AdvancedServerList runs on.
| Placeholder | Description |
|------------------------------|-------------------------------------------------------------------------|
| `${server playersOnline}` | The number of players online on this proxy/server.[^4] |
| `${server playersMax}` | The total number of players that can join this server.[^5] |
| `${server host}` | The domain/IP the player pinged.[^6] |
| `${server whitelistEnabled}` | Whether the whitelist is enabled or not. Only available on Spigot/Paper |
| Placeholder | Description | Platforms |
|------------------------------|------------------------------------------------------------|-----------|
| `${server playersOnline}` | The number of players online on this proxy/server.[^4] | All |
| `${server playersMax}` | The total number of players that can join this server.[^5] | All |
| `${server host}` | The domain/IP the player pinged.[^6] | All |
| `${server whitelistEnabled}` | Whether the whitelist is enabled or not. | Paper |
[^4]:
A comma-separated list of world (On Paper) or Server (On BungeeCord/Velocity) names can be provided to display the added numbers of players in these worlds/servers.
**Example:** `${server playersOnline lobby1,lobby2}` will display the collective numbers of players in the servers `lobby1` and `lobby2`.
[^5]:
When the [`amount` option](../index.md#amount) is used will this placeholder display the modified max players count.
The only exception is [`conditions`](../index.md#conditions) where it uses the actual max players of the server/proxy.
Using either the [extraPlayers' `amount`](index.md#extraplayers-amount) or [maxPlayers' `amount`](index.md#maxplayers-amount) option will make this placeholder return the modified max players count.
Only exception to this rule is when the placeholder is used in the [`condition`](index.md#condition) option in which case it returns the actual max player count of the proxy/server.
[^6]:
An optional server name can be provided to display the IP/Domain associated with that server. Only works on BungeeCord/Velocity.
An optional server name can be provided to display the IP/Domain associated with that server. This only works on BungeeCord or Velocity.
**Example:** `${server host survival}` would display the IP/Domain associated with the `survival` server.
## PlaceholderAPI
@@ -1,60 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2022-2023 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.paper;
import io.papermc.paper.plugin.loader.PluginClasspathBuilder;
import io.papermc.paper.plugin.loader.PluginLoader;
import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.repository.RemoteRepository;
import org.jetbrains.annotations.NotNull;
public class ASLLoader implements PluginLoader{
@Override
public void classloader(@NotNull PluginClasspathBuilder pluginClasspathBuilder){
ComponentLogger logger = pluginClasspathBuilder.getContext().getLogger();
logger.info(Component.text("Loading Libraries for plugin..."));
MavenLibraryResolver resolver = new MavenLibraryResolver();
resolver.addRepository(new RemoteRepository.Builder(
"paper-maven",
"default",
"https://repo.papermc.io/repository/maven-public/"
).build());
logger.info(Component.text("Loading com.squareup.okhttp3:okhttp:4.10.0 from repo.papermc.io..."));
resolver.addDependency(new Dependency(new DefaultArtifact("com.squareup.okhttp3:okhttp:4.10.0"), null));
pluginClasspathBuilder.addLibrary(resolver);
logger.info(Component.text("Loading libraries complete!"));
}
}
@@ -4,7 +4,6 @@ version: '${plugin.version}'
description: '${plugin.description}'
main: 'ch.andre601.advancedserverlist.paper.PaperCore'
loader: 'ch.andre601.advancedserverlist.paper.ASLLoader'
api-version: '1.19'
+1 -1
View File
@@ -38,7 +38,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.build.commit/>
<plugin.version>3.7.0-b2</plugin.version>
<plugin.version>3.8.0</plugin.version>
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
<api.version>v3.1.0</api.version>
+2 -2
View File
@@ -1,4 +1,4 @@
mkdocs-material==9.5.4
mkdocs-glightbox==0.3.6
mkdocs-material==9.5.7
mkdocs-glightbox==0.3.7
mkdocs-awesome-pages-plugin==2.9.2
git+https://github.com/Andre601/mkdocs-pagenav-generator
-10
View File
@@ -81,12 +81,6 @@
<version>4.1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
@@ -114,10 +108,6 @@
<pattern>org.bstats</pattern>
<shadedPattern>ch.andre601.advancedserverlist.velocity.depends.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>okhttp3</pattern>
<shadedPattern>ch.andre601.advancedserverlist.velocity.depends.okhttp3</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
+1 -1
View File
@@ -58,7 +58,7 @@
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.3</version>
<version>5.3.1</version>
<scope>compile</scope>
</dependency>
<dependency>