mirror of
https://codeberg.org/Andre601/AdvancedServerList.git
synced 2026-11-05 09:00:15 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9574d2f83 | ||
|
|
7e45439dfe | ||
|
|
2a8b4ed640 | ||
|
|
86c053e445 | ||
|
|
7eba04bb9a | ||
|
|
b4ac677f67 | ||
|
|
989d44cc5e | ||
|
|
9821875e7a | ||
|
|
07e3b6702b | ||
|
|
31889fbd9c | ||
|
|
87a089a0fa | ||
|
|
88b91e8859 | ||
|
|
f8097e3c72 | ||
|
|
e237c990d8 | ||
|
|
21c0ba975c | ||
|
|
642ce922c3 | ||
|
|
6e5466aacf | ||
|
|
e6635cd844 | ||
|
|
229ab60c57 | ||
|
|
483daee999 | ||
|
|
31ffcd7f7b | ||
|
|
e5139cc00d | ||
|
|
9b1b95b27a | ||
|
|
88d3ceeaf3 | ||
|
|
f74f2f337c | ||
|
|
87b35f240e | ||
|
|
fc861ea304 | ||
|
|
927971ca12 | ||
|
|
0ecb8383e3 | ||
|
|
9c3b2220d5 | ||
|
|
46e15441fd | ||
|
|
2d2a1ca805 | ||
|
|
c577264e1d | ||
|
|
27c3972ab0 | ||
|
|
e4c90730ba | ||
|
|
0694e08399 | ||
|
|
2fefa966dd | ||
|
|
a57cf3df17 | ||
|
|
1ae7260cf3 | ||
|
|
8459eee57d | ||
|
|
f5cebf42ab | ||
|
|
731bdeba7d | ||
|
|
d14cda243a | ||
|
|
0a98aad138 | ||
|
|
1249a08264 | ||
|
|
c0414a5962 | ||
|
|
9cc4d4bb36 | ||
|
|
338358a2ab | ||
|
|
805ba83bb6 | ||
|
|
0f646a8f8d | ||
|
|
2519f09f6f | ||
|
|
60bca9e3d7 | ||
|
|
da8f72fc50 | ||
|
|
c42d4b8967 | ||
|
|
0110854ae4 | ||
|
|
d6d5952cbc | ||
|
|
f9d961cae7 | ||
|
|
a387feea23 | ||
|
|
359c58163b | ||
|
|
0892f5cd1d | ||
|
|
452a7e6dcf | ||
|
|
162dd10a73 |
No files matched your search
@@ -12,6 +12,8 @@ steps:
|
||||
target: modrinth_api_token
|
||||
- source: hangar_api_token
|
||||
target: hangar_api_token
|
||||
- source: discord_webhook_url
|
||||
target: discord_webhook_url
|
||||
commands:
|
||||
# Create the jar files.
|
||||
- mvn clean install
|
||||
@@ -20,7 +22,7 @@ steps:
|
||||
- mv VersionUploader.jar ../../
|
||||
- cd ../../
|
||||
# Execute Jar file
|
||||
- java -jar VersionUploader.jar --modrinth
|
||||
- java -jar VersionUploader.jar --all
|
||||
uploadToCodeberg:
|
||||
image: woodpeckerci/plugin-gitea-release
|
||||
settings:
|
||||
@@ -29,5 +31,6 @@ steps:
|
||||
- "bungeecord/target/AdvancedServerList-*.jar"
|
||||
- "paper/target/AdvancedServerList-*.jar"
|
||||
- "velocity/target/AdvancedServerList-*.jar"
|
||||
- "addons/banplugins/target/AdvancedServerList-*.jar"
|
||||
api_key:
|
||||
from_secret: CB_TOKEN
|
||||
@@ -1,6 +1,6 @@
|
||||
# AdvancedServerList
|
||||
|
||||
AdvancedServerList is a plugin that allowys you to customize your server's MOTD, favicon, Player count text and player count hover displayed in a player's multiplayer server list based on conditions and priorities.
|
||||
AdvancedServerList is a plugin that allows you to customize your server's MOTD, favicon, Player count text and player count hover displayed in a player's multiplayer server list based on conditions and priorities.
|
||||
|
||||
## Downloads
|
||||
|
||||
@@ -30,29 +30,33 @@ AdvancedServerList is a plugin that allowys you to customize your server's MOTD,
|
||||
</a>
|
||||
|
||||
## What is a Server List Profile?
|
||||
|
||||
A Server List Profile refers to a YAML file located in the plugin's `profiles` directory.
|
||||
It allows you to configure specific aspects of the server display in the MC-Client's multiplayer server list, such as the MOTD, player count text, player count hover or Favicon.
|
||||
|
||||
> [*Read More*][profiles]
|
||||
|
||||
### Conditions
|
||||
Thanks to conditions can you determine when a profile should be displayed in the player’s server list, to allow displaying specific text (i.e. a warning when they are using an outdated version).
|
||||
|
||||
When multiple profiles exist that have valid conditions will the one with the highest priority (Higher number = higher priority) be selected. Having no conditions makes the profile automatically return true.
|
||||
Thanks to conditions can you determine when a profile should be displayed in the player's server list, to allow displaying specific text (i.e. a warning when they are using an outdated version).
|
||||
|
||||
When multiple profiles exist that have valid conditions will the one with the highest priority (Higher number = higher priority) be selected. Having no conditions makes it automatically true.
|
||||
|
||||
> [*Read More*][conditions]
|
||||
|
||||
### Placeholders
|
||||
|
||||
Placeholders can be used within conditions to further customize them. They can also be used in any other text option to display their respective values.
|
||||
The format is `${<target> <identifier>}` which was adopted from BungeeTabListPlus. Depending on what platform you use the plugin on are only specific placeholders available.
|
||||
|
||||
When using the SpigotMC/PaperMC version, or while PAPIProxyBridge is installed on your proxy, can you also use placeholders from [PlaceholderAPI][placeholderapi] using its `%<identifier>_<values>%` placeholder format. PlaceholderAPI needs to be installed for that.
|
||||
When using the SpigotMC/PaperMC version, or while [PAPIProxyBridge][papiproxybridge] is installed on your proxy, can you also use placeholders from [PlaceholderAPI][placeholderapi] using its `%<identifier>_<values>%` placeholder format. PlaceholderAPI needs to be installed on the server (not proxy) for that.
|
||||
|
||||
If you're a plugin dev can you even add your own custom placeholders through AdvancedServerList's own API.
|
||||
|
||||
> [*Read More*][placeholders]
|
||||
|
||||
### Formatting
|
||||
|
||||
The plugin uses the MiniMessage format for a consistent, easy way of formatting your text.
|
||||
Only certain options are usable for each option. As an example does motd support HEX colours and gradients, while the other options only support default colour codes.
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>ch.andre601.advancedserverlist</groupId>
|
||||
<version>parent</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>banplugins</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>${plugin.version}</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>16</maven.compiler.source>
|
||||
<maven.compiler.target>16</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>sonatype</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>papermc</id>
|
||||
<url>https://papermc.io/repo/repository/maven-public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- Proxy/Server -->
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.20-R0.2</version>
|
||||
<type>jar</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.20-R0.2</version>
|
||||
<type>javadoc</type>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.20-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Plugin APIs -->
|
||||
<dependency>
|
||||
<groupId>com.github.DevLeoko</groupId>
|
||||
<artifactId>AdvancedBan</artifactId>
|
||||
<version>v2.3.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>${api.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>AdvancedServerList-BanPlugins-Addon-${plugin.version}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.12.1</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.banplugins.bungeecord;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import ch.andre601.advancedserverlist.banplugins.placeholders.AdvancedBanPlaceholders;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum BungeeCordBanPlugins{
|
||||
|
||||
ADVANCED_BAN("AdvancedBan", new AdvancedBanPlaceholders());
|
||||
|
||||
private final String plugin;
|
||||
private final PlaceholderProvider placeholderProvider;
|
||||
|
||||
BungeeCordBanPlugins(String plugin, PlaceholderProvider placeholderProvider){
|
||||
this.plugin = plugin;
|
||||
this.placeholderProvider = placeholderProvider;
|
||||
}
|
||||
|
||||
public static Map<String, PlaceholderProvider> getBanPlugins(){
|
||||
Map<String, PlaceholderProvider> content = new HashMap<>();
|
||||
|
||||
for(BungeeCordBanPlugins bungeeCordBanPlugins : BungeeCordBanPlugins.values()){
|
||||
content.put(bungeeCordBanPlugins.plugin, bungeeCordBanPlugins.placeholderProvider);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.banplugins.bungeecord;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.AdvancedServerListAPI;
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class BungeeCordBanPluginsAddon extends Plugin{
|
||||
|
||||
@Override
|
||||
public void onEnable(){
|
||||
if(getProxy().getPluginManager().getPlugin("AdvancedServerList") == null){
|
||||
getLogger().warning("AdvancedServerList is not enabled. This plugin requires it to function!");
|
||||
return;
|
||||
}
|
||||
|
||||
int loadedPlaceholders = loadPlaceholderProviders();
|
||||
if(loadedPlaceholders == 0){
|
||||
getLogger().warning("No compatible Ban plugin was found to register placeholders for.");
|
||||
}else{
|
||||
getLogger().info("Loaded " + loadedPlaceholders + " Placeholder Set(s) for AdvancedServerList!");
|
||||
}
|
||||
}
|
||||
|
||||
private int loadPlaceholderProviders(){
|
||||
int loaded = 0;
|
||||
Map<String, PlaceholderProvider> banPlugins = BungeeCordBanPlugins.getBanPlugins();
|
||||
AdvancedServerListAPI api = AdvancedServerListAPI.get();
|
||||
|
||||
for(Map.Entry<String, PlaceholderProvider> entry : banPlugins.entrySet()){
|
||||
if(getProxy().getPluginManager().getPlugin(entry.getKey()) != null){
|
||||
getLogger().info("Registering Placeholders for " + entry.getKey() + "...");
|
||||
api.addPlaceholderProvider(entry.getValue());
|
||||
getLogger().info("Placeholder successfully registered!");
|
||||
|
||||
loaded++;
|
||||
}
|
||||
}
|
||||
|
||||
return loaded;
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.banplugins.paper;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import ch.andre601.advancedserverlist.banplugins.placeholders.AdvancedBanPlaceholders;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum PaperBanPlugins{
|
||||
|
||||
ADVANCED_BAN("AdvancedBan", new AdvancedBanPlaceholders());
|
||||
|
||||
private final String plugin;
|
||||
private final PlaceholderProvider placeholderProvider;
|
||||
|
||||
PaperBanPlugins(String plugin, PlaceholderProvider placeholderProvider){
|
||||
this.plugin = plugin;
|
||||
this.placeholderProvider = placeholderProvider;
|
||||
}
|
||||
|
||||
public static Map<String, PlaceholderProvider> getBanPlugins(){
|
||||
Map<String, PlaceholderProvider> content = new HashMap<>();
|
||||
|
||||
for(PaperBanPlugins paperBanPlugins : PaperBanPlugins.values()){
|
||||
content.put(paperBanPlugins.plugin, paperBanPlugins.placeholderProvider);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.banplugins.paper;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.AdvancedServerListAPI;
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class PaperBanPluginsAddon extends JavaPlugin{
|
||||
|
||||
@Override
|
||||
public void onEnable(){
|
||||
if(!getServer().getPluginManager().isPluginEnabled("AdvancedServerList")){
|
||||
getLogger().warning("AdvancedServerList is not enabled. This plugin requires it to function!");
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
|
||||
int loadedPlaceholders = loadPlaceholderProviders();
|
||||
if(loadedPlaceholders == 0){
|
||||
getLogger().warning("No compatible Ban plugin was found to register placeholders for. Disabling plugin...");
|
||||
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
}else{
|
||||
getLogger().info("Loaded " + loadedPlaceholders + " Placeholder Set(s) for AdvancedServerList!");
|
||||
}
|
||||
}
|
||||
|
||||
private int loadPlaceholderProviders(){
|
||||
int loaded = 0;
|
||||
Map<String, PlaceholderProvider> banPlugins = PaperBanPlugins.getBanPlugins();
|
||||
AdvancedServerListAPI api = AdvancedServerListAPI.get();
|
||||
|
||||
for(Map.Entry<String, PlaceholderProvider> entry : banPlugins.entrySet()){
|
||||
if(getServer().getPluginManager().isPluginEnabled(entry.getKey())){
|
||||
getLogger().info("Registering Placeholders for " + entry.getKey() + "...");
|
||||
api.addPlaceholderProvider(entry.getValue());
|
||||
getLogger().info("Placeholder successfully registered!");
|
||||
|
||||
loaded++;
|
||||
}
|
||||
}
|
||||
|
||||
return loaded;
|
||||
}
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.banplugins.placeholders;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.banplugins.providers.AdvancedBanProvider;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class AdvancedBanPlaceholders extends PlaceholderProvider{
|
||||
|
||||
private final AdvancedBanProvider provider = new AdvancedBanProvider();
|
||||
|
||||
public AdvancedBanPlaceholders(){
|
||||
super("advancedban");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
|
||||
String[] args = placeholder.split("\\s");
|
||||
|
||||
return switch(args[0]) {
|
||||
// Mute-related placeholders
|
||||
case "isMuted" -> String.valueOf(provider.muted(player));
|
||||
case "muteReason" -> provider.muteReason(player);
|
||||
case "muteDuration" -> {
|
||||
if(args.length == 1)
|
||||
yield provider.muteDuration(player);
|
||||
|
||||
if(args.length > 2)
|
||||
yield null;
|
||||
|
||||
boolean fromStart = Boolean.getBoolean(args[1]);
|
||||
yield provider.muteDuration(player, fromStart);
|
||||
}
|
||||
case "muteExpiration" -> {
|
||||
if(args.length == 1)
|
||||
yield provider.muteExpirationDate(player);
|
||||
|
||||
String pattern = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
|
||||
|
||||
yield provider.banExpirationDate(player, pattern);
|
||||
}
|
||||
|
||||
// Ban-related placeholders
|
||||
case "isBanned" -> String.valueOf(provider.banned(player));
|
||||
case "banReason" -> provider.banReason(player);
|
||||
case "banDuration" -> {
|
||||
if(args.length == 1)
|
||||
yield provider.banDuration(player);
|
||||
|
||||
if(args.length > 2)
|
||||
yield null;
|
||||
|
||||
boolean fromStart = Boolean.getBoolean(args[1]);
|
||||
yield provider.banDuration(player, fromStart);
|
||||
}
|
||||
case "banExpiration" -> {
|
||||
if(args.length == 1)
|
||||
yield provider.banExpirationDate(player);
|
||||
|
||||
String pattern = String.join(" ", Arrays.copyOfRange(args, 1, args.length));
|
||||
|
||||
yield provider.banExpirationDate(player, pattern);
|
||||
}
|
||||
|
||||
// Unknown/Invalid placeholder.
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.banplugins.providers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.primitives.UnsignedLongs;
|
||||
import me.leoko.advancedban.manager.PunishmentManager;
|
||||
import me.leoko.advancedban.utils.Punishment;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AdvancedBanProvider implements PunishmentProvider{
|
||||
|
||||
private static PunishmentManager getAPI(){
|
||||
return PunishmentManager.get();
|
||||
}
|
||||
|
||||
private static String noDashesUUID(UUID uuid){
|
||||
return hexString(uuid.getMostSignificantBits()) + hexString(uuid.getLeastSignificantBits());
|
||||
}
|
||||
|
||||
private static Punishment mute(GenericPlayer player){
|
||||
return getAPI().getMute(noDashesUUID(player.getUUID()));
|
||||
}
|
||||
|
||||
private static Punishment ban(GenericPlayer player){
|
||||
return getAPI().getBan(noDashesUUID(player.getUUID()));
|
||||
}
|
||||
|
||||
private static String hexString(long unsigned){
|
||||
return Strings.padStart(UnsignedLongs.toString(unsigned, 16), 16, '0');
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean muted(GenericPlayer player){
|
||||
return getAPI().isMuted(noDashesUUID(player.getUUID()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean banned(GenericPlayer player){
|
||||
return getAPI().isBanned(noDashesUUID(player.getUUID()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String muteReason(GenericPlayer player){
|
||||
Punishment mute = mute(player);
|
||||
if(mute == null)
|
||||
return null;
|
||||
|
||||
return mute.getReason();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String banReason(GenericPlayer player){
|
||||
Punishment ban = ban(player);
|
||||
if(ban == null)
|
||||
return null;
|
||||
|
||||
return ban.getReason();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String muteDuration(GenericPlayer player){
|
||||
return muteDuration(player, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String banDuration(GenericPlayer player){
|
||||
return banDuration(player, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String muteExpirationDate(GenericPlayer player, String pattern){
|
||||
Punishment mute = mute(player);
|
||||
if(mute == null)
|
||||
return null;
|
||||
|
||||
long end = mute.getEnd();
|
||||
if(end < 0L)
|
||||
return "never";
|
||||
|
||||
Date date = new Date(end);
|
||||
return new SimpleDateFormat(pattern).format(date);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String banExpirationDate(GenericPlayer player, String pattern){
|
||||
Punishment ban = ban(player);
|
||||
if(ban == null)
|
||||
return null;
|
||||
|
||||
long end = ban.getEnd();
|
||||
if(end < 0L)
|
||||
return "never";
|
||||
|
||||
Date date = new Date(end);
|
||||
return new SimpleDateFormat(pattern).format(date);
|
||||
}
|
||||
|
||||
public String muteDuration(GenericPlayer player, boolean fromStart){
|
||||
Punishment mute = mute(player);
|
||||
if(mute == null)
|
||||
return null;
|
||||
|
||||
return mute.getDuration(fromStart);
|
||||
}
|
||||
|
||||
public String banDuration(GenericPlayer player, boolean fromStart){
|
||||
Punishment ban = ban(player);
|
||||
if(ban == null)
|
||||
return null;
|
||||
|
||||
return ban.getDuration(fromStart);
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.banplugins.providers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
|
||||
public interface PunishmentProvider{
|
||||
|
||||
boolean muted(GenericPlayer player);
|
||||
|
||||
boolean banned(GenericPlayer player);
|
||||
|
||||
String muteReason(GenericPlayer player);
|
||||
|
||||
String banReason(GenericPlayer player);
|
||||
|
||||
String muteDuration(GenericPlayer player);
|
||||
|
||||
String banDuration(GenericPlayer player);
|
||||
|
||||
default String muteExpirationDate(GenericPlayer player){
|
||||
return muteExpirationDate(player, "dd, MMM yyyy HH:mm:ss");
|
||||
}
|
||||
|
||||
String muteExpirationDate(GenericPlayer player, String pattern);
|
||||
|
||||
default String banExpirationDate(GenericPlayer player){
|
||||
return banExpirationDate(player, "dd, MMM yyyy HH:mm:ss");
|
||||
}
|
||||
|
||||
String banExpirationDate(GenericPlayer player, String pattern);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
name: 'ASLBanPluginsAddon'
|
||||
author: 'Andre_601'
|
||||
version: '${plugin.version}'
|
||||
description: 'AdvancedBan Add-on for AdvancedServerList to add placeholders to use.'
|
||||
|
||||
softDepends:
|
||||
- AdvancedServerList
|
||||
- AdvancedBan
|
||||
|
||||
main: 'ch.andre601.advancedserverlist.banplugins.bungeecord.BungeeCordBanPluginsAddon'
|
||||
@@ -0,0 +1,16 @@
|
||||
name: 'ASLBanPluginsAddon'
|
||||
author: 'Andre_601'
|
||||
version: '${plugin.version}'
|
||||
|
||||
main: 'ch.andre601.advancedserverlist.banplugins.paper.AdvancedBanPlaceholders'
|
||||
|
||||
api-version: '1.19'
|
||||
|
||||
dependencies:
|
||||
server:
|
||||
AdvancedServerList:
|
||||
required: false
|
||||
load: BEFORE
|
||||
AdvancedBans:
|
||||
required: false
|
||||
load: BEFORE
|
||||
+3
-3
@@ -81,13 +81,13 @@
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-api</artifactId>
|
||||
<version>4.15.0</version>
|
||||
<version>4.16.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-text-minimessage</artifactId>
|
||||
<version>4.15.0</version>
|
||||
<version>4.16.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -127,7 +127,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<version>3.5.2</version>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<relocations>
|
||||
|
||||
+12
-1
@@ -40,6 +40,7 @@ import net.md_5.bungee.api.plugin.Plugin;
|
||||
import org.bstats.bungeecord.Metrics;
|
||||
import org.bstats.charts.SimplePie;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
|
||||
@@ -77,12 +78,17 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFaviconHandler(AdvancedServerList<Favicon> core){
|
||||
faviconHandler = new FaviconHandler<>(core);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearFaviconCache(){
|
||||
if(faviconHandler == null)
|
||||
return;
|
||||
|
||||
faviconHandler.clearCache();
|
||||
faviconHandler.cleanCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,4 +128,9 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
|
||||
public String getLoader(){
|
||||
return "bungeecord";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Favicon createFavicon(BufferedImage image) throws IllegalArgumentException{
|
||||
return Favicon.create(image);
|
||||
}
|
||||
}
|
||||
+1
-7
@@ -25,11 +25,11 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.bungeecord.listeners;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
|
||||
import ch.andre601.advancedserverlist.bungeecord.objects.BungeePlayerImpl;
|
||||
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
|
||||
import ch.andre601.advancedserverlist.bungeecord.objects.BungeeProxyImpl;
|
||||
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
@@ -46,7 +46,6 @@ import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.ProxyPingEvent;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -205,9 +204,4 @@ public class BungeeEventWrapper implements GenericEventWrapper<Favicon, BungeePl
|
||||
|
||||
return new BungeeProxyImpl(servers, playersOnline, playersMax, host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Favicon createFavicon(BufferedImage image) throws IllegalArgumentException{
|
||||
return Favicon.create(image);
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -41,7 +41,7 @@
|
||||
<properties>
|
||||
<maven.compiler.source>16</maven.compiler.source>
|
||||
<maven.compiler.target>16</maven.compiler.target>
|
||||
<plugin.config.version>3</plugin.config.version>
|
||||
<plugin.config.version>4</plugin.config.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
@@ -77,19 +77,19 @@
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-api</artifactId>
|
||||
<version>4.15.0</version>
|
||||
<version>4.16.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-text-minimessage</artifactId>
|
||||
<version>4.15.0</version>
|
||||
<version>4.16.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-text-serializer-legacy</artifactId>
|
||||
<version>4.15.0</version>
|
||||
<version>4.16.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -129,7 +129,7 @@
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.10.1</version>
|
||||
<version>5.10.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -151,7 +151,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<version>3.5.2</version>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<filters>
|
||||
|
||||
@@ -36,7 +36,6 @@ import ch.andre601.advancedserverlist.core.profiles.players.PlayerHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
@@ -148,9 +147,7 @@ public class AdvancedServerList<F>{
|
||||
return;
|
||||
}
|
||||
|
||||
Path folder = getPlugin().getFolderPath().resolve("favicons");
|
||||
if(!folder.toFile().exists() && folder.toFile().mkdirs())
|
||||
getPlugin().getPluginLogger().info("Successfully created favicons folder.");
|
||||
getPlugin().loadFaviconHandler(this);
|
||||
|
||||
getPlugin().getPluginLogger().info("Loading Commands...");
|
||||
plugin.loadCommands();
|
||||
|
||||
@@ -27,7 +27,10 @@ package ch.andre601.advancedserverlist.core.compat.papi;
|
||||
|
||||
import net.william278.papiproxybridge.api.PlaceholderAPI;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
|
||||
+5
-13
@@ -30,10 +30,10 @@ import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.compat.maintenance.MaintenanceUtil;
|
||||
import ch.andre601.advancedserverlist.core.compat.papi.PAPIUtil;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
|
||||
import ch.andre601.advancedserverlist.core.compat.papi.PAPIUtil;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
|
||||
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileManager;
|
||||
@@ -148,26 +148,18 @@ public class PingEventHandler{
|
||||
if(ProfileManager.checkOption(entry.favicon())){
|
||||
logger.debug(PingEventHandler.class, "Favicon set. Resolving '%s'...", entry.favicon());
|
||||
|
||||
String favicon = StringReplacer.replace(entry.favicon(), player, server);
|
||||
String faviconString = StringReplacer.replace(entry.favicon(), player, server);
|
||||
|
||||
F fav = plugin.getFaviconHandler().getFavicon(favicon, image -> {
|
||||
try{
|
||||
logger.debug(PingEventHandler.class, "Converting BufferedImage to Server or Proxy Favicon instance...");
|
||||
return event.createFavicon(image);
|
||||
}catch(Exception ex){
|
||||
plugin.getPluginLogger().warn("Encountered an Exception while creating Favicon!", ex);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
F favicon = plugin.getFaviconHandler().getFavicon(faviconString);
|
||||
|
||||
if(fav == null){
|
||||
if(favicon == null){
|
||||
logger.debugWarn(PingEventHandler.class, "Favicon was invalid or not yet resolved! Using default favicon of Server/Proxy...");
|
||||
|
||||
event.setDefaultFavicon();
|
||||
}else{
|
||||
logger.debug(PingEventHandler.class, "Applying favicon...");
|
||||
|
||||
event.setFavicon(fav);
|
||||
event.setFavicon(favicon);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,18 +46,29 @@ public class ConfigMigrator{
|
||||
public static ConfigurationTransformation.Versioned create(){
|
||||
return ConfigurationTransformation.versionedBuilder()
|
||||
.versionKey("configVersion")
|
||||
.addVersion(LATEST, twoToThree())
|
||||
.addVersion(LATEST, threeToFour())
|
||||
.addVersion(3, twoToThree())
|
||||
.addVersion(2, oneToTwo())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ConfigurationTransformation threeToFour(){
|
||||
return ConfigurationTransformation.builder()
|
||||
.addAction(NodePath.path(), (path, value) -> {
|
||||
value.node("faviconCacheTime").set(1);
|
||||
|
||||
return null;
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ConfigurationTransformation twoToThree(){
|
||||
return ConfigurationTransformation.builder()
|
||||
.addAction(NodePath.path(), ((path, value) -> {
|
||||
.addAction(NodePath.path(), (path, value) -> {
|
||||
value.node("debug").set(false);
|
||||
|
||||
return null;
|
||||
}))
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,10 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.file;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileSerializer;
|
||||
import org.spongepowered.configurate.ConfigurateException;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
@@ -165,7 +165,7 @@ public class FileHandler{
|
||||
return false;
|
||||
}
|
||||
|
||||
profiles.sort(Comparator.comparing(ServerListProfile::getPriority).reversed());
|
||||
profiles.sort(Comparator.comparing(ServerListProfile::priority).reversed());
|
||||
return !profiles.isEmpty();
|
||||
}
|
||||
|
||||
@@ -191,6 +191,11 @@ public class FileHandler{
|
||||
return node.node(path).getBoolean();
|
||||
}
|
||||
|
||||
public long getLong(long def, long limit, Object... path){
|
||||
long value = node.node(path).getLong(def);
|
||||
return Math.max(value, limit);
|
||||
}
|
||||
|
||||
public boolean isOldConfig(){
|
||||
return node.node("configVersion").virtual() || node.node("configVersion").getInt(0) < ConfigMigrator.LATEST;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public interface PluginCore<F>{
|
||||
@@ -39,6 +40,8 @@ public interface PluginCore<F>{
|
||||
|
||||
void loadMetrics();
|
||||
|
||||
void loadFaviconHandler(AdvancedServerList<F> core);
|
||||
|
||||
void clearFaviconCache();
|
||||
|
||||
AdvancedServerList<F> getCore();
|
||||
@@ -55,7 +58,12 @@ public interface PluginCore<F>{
|
||||
|
||||
String getLoader();
|
||||
|
||||
F createFavicon(BufferedImage image) throws Exception;
|
||||
|
||||
default boolean isDebugEnabled(){
|
||||
if(getCore() == null)
|
||||
return false;
|
||||
|
||||
return getCore().getFileHandler().getBoolean("debug");
|
||||
}
|
||||
}
|
||||
+1
-4
@@ -25,15 +25,14 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.interfaces.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
@@ -79,8 +78,6 @@ public interface GenericEventWrapper<F, P extends GenericPlayer>{
|
||||
|
||||
GenericServer createGenericServer(int playersOnline, int playersMax, String host);
|
||||
|
||||
F createFavicon(BufferedImage image) throws Exception;
|
||||
|
||||
default String resolveHost(InetSocketAddress address){
|
||||
return address == null ? null : address.getHostString();
|
||||
}
|
||||
|
||||
+16
-88
@@ -29,63 +29,34 @@ import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.Expression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionEngine;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionErrorTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class ServerListProfile{
|
||||
|
||||
private final int priority;
|
||||
private final String condition;
|
||||
private final List<Expression> expressions;
|
||||
private final ProfileEntry defaultProfile;
|
||||
|
||||
private final List<ProfileEntry> profiles;
|
||||
|
||||
private final Random random = new Random();
|
||||
|
||||
public ServerListProfile(int priority, String condition, List<Expression> expressions, ProfileEntry defaultProfile, List<ProfileEntry> profiles){
|
||||
this.priority = priority;
|
||||
this.condition = condition;
|
||||
this.expressions = expressions;
|
||||
this.defaultProfile = defaultProfile;
|
||||
|
||||
this.profiles = profiles;
|
||||
}
|
||||
|
||||
public int getPriority(){
|
||||
return priority;
|
||||
}
|
||||
public record ServerListProfile(int priority, String condition, ProfileEntry defaultProfile, List<ProfileEntry> profiles){
|
||||
private static final Random random = new Random();
|
||||
|
||||
public boolean evalConditions(ExpressionEngine expressionEngine, PluginLogger logger, GenericPlayer player, GenericServer server){
|
||||
if(condition != null && !condition.isEmpty()){
|
||||
ExpressionTemplate template = expressionEngine.compile(condition, logger, player, server);
|
||||
if(template instanceof ExpressionErrorTemplate errorTemplate){
|
||||
logger.warn(errorTemplate.instantiateWithStringResult().evaluate());
|
||||
return true;
|
||||
}
|
||||
|
||||
return template.instantiateWithBooleanResult().evaluate();
|
||||
}
|
||||
|
||||
if(expressions.isEmpty())
|
||||
if(condition == null || condition.isEmpty())
|
||||
return true;
|
||||
|
||||
for(Expression expression : expressions){
|
||||
if(!expression.evaluate(player, server))
|
||||
ExpressionsWarnHelper warnHelper = new ExpressionsWarnHelper(condition);
|
||||
ExpressionTemplate template = expressionEngine.compile(condition, player, server, warnHelper);
|
||||
|
||||
if(warnHelper.hasWarnings()){
|
||||
warnHelper.printWarnings(logger);
|
||||
|
||||
if(template == null)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return template.instantiateWithBooleanResult().evaluate();
|
||||
}
|
||||
|
||||
public ProfileEntry getRandomProfile(){
|
||||
@@ -101,10 +72,6 @@ public class ServerListProfile{
|
||||
}
|
||||
}
|
||||
|
||||
public ProfileEntry getDefaultProfile(){
|
||||
return defaultProfile;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the Profile...
|
||||
* ...doesn't have any valid MOTD set AND
|
||||
@@ -113,12 +80,12 @@ public class ServerListProfile{
|
||||
* ...doesn't have a favicon set.
|
||||
*/
|
||||
public boolean isInvalidProfile(){
|
||||
if(profiles.isEmpty())
|
||||
return defaultProfile.isInvalid();
|
||||
if(profiles().isEmpty())
|
||||
return defaultProfile().isInvalid();
|
||||
|
||||
boolean profilesValid = false;
|
||||
|
||||
for(ProfileEntry profile : profiles){
|
||||
for(ProfileEntry profile : profiles()){
|
||||
if(profile.isInvalid())
|
||||
continue;
|
||||
|
||||
@@ -134,7 +101,6 @@ public class ServerListProfile{
|
||||
private final String fileName;
|
||||
private final ConfigurationNode node;
|
||||
private final int priority;
|
||||
private final List<Expression> expressions = new ArrayList<>();
|
||||
|
||||
private final PluginLogger logger;
|
||||
|
||||
@@ -152,7 +118,6 @@ public class ServerListProfile{
|
||||
public static Builder resolve(String fileName, ConfigurationNode node, PluginLogger logger){
|
||||
return new Builder(fileName, node, logger)
|
||||
.resolveCondition()
|
||||
.resolveExpressions()
|
||||
.resolveProfiles()
|
||||
.resolveDefaultProfile();
|
||||
}
|
||||
@@ -166,43 +131,6 @@ public class ServerListProfile{
|
||||
return this;
|
||||
}
|
||||
|
||||
private Builder resolveExpressions(){
|
||||
List<String> temp;
|
||||
try{
|
||||
temp = node.node("conditions").getList(String.class);
|
||||
}catch(SerializationException ex){
|
||||
logger.warn("Encountered a SerializationException while resolving conditions for %s", ex, fileName);
|
||||
return this;
|
||||
}
|
||||
|
||||
if(temp == null || temp.isEmpty())
|
||||
return this;
|
||||
|
||||
StringJoiner joiner = new StringJoiner(" and ");
|
||||
|
||||
for(String str : temp){
|
||||
Expression expr = Expression.resolve(str);
|
||||
|
||||
if(expr.getResult() != Expression.ExpressionResult.VALID){
|
||||
logger.warn("Found invalid expression in condition '%s'! Reason: %s", str, expr.getResult().getMessage());
|
||||
continue;
|
||||
}
|
||||
|
||||
joiner.add(str);
|
||||
this.expressions.add(expr);
|
||||
}
|
||||
|
||||
if(!this.expressions.isEmpty()){
|
||||
logger.warn("'%s' uses 'conditions' which is deprecated in favour of the newer 'condition' option.", fileName);
|
||||
logger.warn("The 'conditions' option will be removed in a future version.");
|
||||
logger.warn("");
|
||||
logger.warn("Please migrate your condition(s) over from the old option to the new option like this:");
|
||||
logger.warn("consition: '%s'", joiner.toString());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private Builder resolveProfiles(){
|
||||
try{
|
||||
this.profiles = node.node("profiles").getList(ProfileEntry.class);
|
||||
@@ -223,7 +151,7 @@ public class ServerListProfile{
|
||||
}
|
||||
|
||||
public ServerListProfile build(){
|
||||
return new ServerListProfile(this.priority, this.condition, this.expressions, this.defaultProfile, this.profiles);
|
||||
return new ServerListProfile(this.priority, this.condition, this.defaultProfile, this.profiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -27,7 +27,7 @@ package ch.andre601.advancedserverlist.core.profiles.conditions;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers.TokenReader;
|
||||
import com.google.common.collect.Ordering;
|
||||
@@ -47,7 +47,7 @@ public class ExpressionTokenizer{
|
||||
this.tokenReaders = TOKEN_READER_ORDERING.immutableSortedCopy(tokenReaders);
|
||||
}
|
||||
|
||||
public List<Token> parse(String text, PluginLogger logger, GenericPlayer player, GenericServer server){
|
||||
public List<Token> parse(String text, GenericPlayer player, GenericServer server, ExpressionsWarnHelper warnHelper){
|
||||
ParsePosition position = new ParsePosition(0);
|
||||
|
||||
List<Token> tokens = new LinkedList<>();
|
||||
@@ -63,13 +63,13 @@ public class ExpressionTokenizer{
|
||||
|
||||
for(TokenReader tokenReader : tokenReaders){
|
||||
Token token;
|
||||
if(null != (token = tokenReader.read(text, position, player, server))){
|
||||
if(null != (token = tokenReader.read(text, position, player, server, warnHelper))){
|
||||
tokens.add(token);
|
||||
continue next_token;
|
||||
}
|
||||
}
|
||||
|
||||
logger.warn("Illegal token '%c' at index %d.", text.charAt(position.getIndex()), position.getIndex());
|
||||
warnHelper.appendWarning(position.getIndex(), "Illegal token '%c'.", text.charAt(position.getIndex()));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -27,7 +27,6 @@ package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.ExpressionTokenizer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.ListOperator;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.Operator;
|
||||
@@ -62,8 +61,8 @@ public class ExpressionEngine{
|
||||
this.templateParser = new ExpressionTemplateParser(options.operators, options.valueReaders);
|
||||
}
|
||||
|
||||
public ExpressionTemplate compile(String expression, PluginLogger logger, GenericPlayer player, GenericServer server){
|
||||
return templateParser.parse(tokenizer.parse(expression, logger, player, server));
|
||||
public ExpressionTemplate compile(String expression, GenericPlayer player, GenericServer server, ExpressionsWarnHelper warnHelper){
|
||||
return templateParser.parse(tokenizer.parse(expression, player, server, warnHelper), warnHelper);
|
||||
}
|
||||
|
||||
public static class Options{
|
||||
@@ -94,13 +93,14 @@ public class ExpressionEngine{
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.OR, "or"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.OR, "||"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL, "=="))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL_IGNORE_CASE, "=~"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL, "="))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.EQUAL_IGNORE_CASE, "~"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.NOT_EQUAL, "!="))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.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.CONTAINS, "<_"))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.GREATER_OR_EQUAL_THAN, ">="))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.LESSER_OR_EQUAL_THAN, "<="))
|
||||
.tokenReader(new PatternTokenReader(DefaultTokens.OPENING_PARENTHESIS, "("))
|
||||
|
||||
+24
-20
@@ -23,36 +23,40 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.templates;
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.expressions;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToBooleanExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToDoubleExpression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ToStringExpression;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
|
||||
public class ExpressionErrorTemplate implements ExpressionTemplate{
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ExpressionsWarnHelper{
|
||||
|
||||
private final String msg;
|
||||
private final String expression;
|
||||
private final List<Context> warnings = new ArrayList<>();
|
||||
|
||||
private ExpressionErrorTemplate(String msg){
|
||||
this.msg = msg;
|
||||
public ExpressionsWarnHelper(String expression){
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public static ExpressionErrorTemplate of(String msg){
|
||||
return new ExpressionErrorTemplate(msg);
|
||||
public void appendWarning(int position, String warning, Object... args){
|
||||
warnings.add(new Context(position, String.format(warning, args)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToStringExpression instantiateWithStringResult(){
|
||||
return ToStringExpression.literal(msg);
|
||||
public boolean hasWarnings(){
|
||||
return !warnings.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToDoubleExpression instantiateWithDoubleResult(){
|
||||
return ToDoubleExpression.literal(0);
|
||||
public void printWarnings(PluginLogger logger){
|
||||
logger.warn("Encountered %d issue(s) while parsing expression '%s'", warnings.size(), expression);
|
||||
for(Context warning : warnings){
|
||||
if(warning.position() > -1){
|
||||
logger.warn(" - At Position %d: %s", warning.position(), warning.message());
|
||||
}else{
|
||||
logger.warn(" - Cause: %s", warning.message());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return ToBooleanExpression.literal(false);
|
||||
}
|
||||
public record Context(int position, String message){}
|
||||
}
|
||||
+2
-1
@@ -25,6 +25,7 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ConstantExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.BooleanToken;
|
||||
@@ -35,7 +36,7 @@ import java.util.List;
|
||||
public class BooleanConstantReader extends ValueReader{
|
||||
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList, ExpressionsWarnHelper warnHelper){
|
||||
if(tokenList.get(0) instanceof BooleanToken){
|
||||
return ConstantExpressionTemplate.of(((BooleanToken)tokenList.remove(0)).getValue());
|
||||
}
|
||||
|
||||
+14
-10
@@ -25,9 +25,9 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.ListOperator;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.operators.Operator;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionErrorTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
@@ -47,32 +47,36 @@ public class ExpressionTemplateParser{
|
||||
this.valueReaders = valueReaders;
|
||||
}
|
||||
|
||||
public ExpressionTemplate parse(List<Token> tokenList){
|
||||
public ExpressionTemplate parse(List<Token> tokenList, ExpressionsWarnHelper warnHelper){
|
||||
List<ExpressionTemplate> parts = new ArrayList<>();
|
||||
List<Operator> operators = new ArrayList<>();
|
||||
|
||||
try{
|
||||
parts.add(read(tokenList));
|
||||
parts.add(read(tokenList, warnHelper));
|
||||
}catch(IllegalArgumentException ex){
|
||||
return ExpressionErrorTemplate.of(ex.getMessage());
|
||||
warnHelper.appendWarning(-1, ex.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
while(!tokenList.isEmpty()){
|
||||
Token token = tokenList.remove(0);
|
||||
Operator operator = this.operators.get(token);
|
||||
if(operator == null){
|
||||
return ExpressionErrorTemplate.of("Error while parsing Expression. Got \"" + token + "\" but expected OPERATOR.");
|
||||
warnHelper.appendWarning(-1, "Received \"%s\" but expected OPERATOR.", token);
|
||||
return null;
|
||||
}
|
||||
|
||||
operators.add(operator);
|
||||
if(tokenList.isEmpty()){
|
||||
return ExpressionErrorTemplate.of("Received unexpected end of input.");
|
||||
warnHelper.appendWarning(-1, "Received unexpected end of input.");
|
||||
return null;
|
||||
}
|
||||
|
||||
try{
|
||||
parts.add(read(tokenList));
|
||||
parts.add(read(tokenList, warnHelper));
|
||||
}catch(IllegalArgumentException ex){
|
||||
return ExpressionErrorTemplate.of(ex.getMessage());
|
||||
warnHelper.appendWarning(-1, ex.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,9 +125,9 @@ public class ExpressionTemplateParser{
|
||||
return parts.get(0);
|
||||
}
|
||||
|
||||
ExpressionTemplate read(List<Token> tokenList){
|
||||
ExpressionTemplate read(List<Token> tokenList, ExpressionsWarnHelper warnHelper){
|
||||
for(ValueReader valueReader : valueReaders){
|
||||
ExpressionTemplate template = valueReader.read(this, tokenList);
|
||||
ExpressionTemplate template = valueReader.read(this, tokenList, warnHelper);
|
||||
if(template != null)
|
||||
return template;
|
||||
}
|
||||
|
||||
+3
-2
@@ -25,6 +25,7 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
@@ -40,10 +41,10 @@ public class NegatedExpressionReader extends ValueReader{
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList, ExpressionsWarnHelper warnHelper){
|
||||
if(tokenList.get(0) == tokenNegation){
|
||||
tokenList.remove(0);
|
||||
return ExpressionTemplates.negate(parser.read(tokenList));
|
||||
return ExpressionTemplates.negate(parser.read(tokenList, warnHelper));
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
+3
-2
@@ -25,6 +25,7 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplates;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
@@ -40,10 +41,10 @@ public class NegatedNumberReader extends ValueReader{
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList, ExpressionsWarnHelper warnHelper){
|
||||
if(tokenList.get(0) == tokenNegation){
|
||||
tokenList.remove(0);
|
||||
return ExpressionTemplates.negateNumber(parser.read(tokenList));
|
||||
return ExpressionTemplates.negateNumber(parser.read(tokenList, warnHelper));
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ConstantExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.NumberToken;
|
||||
@@ -34,7 +35,7 @@ import java.util.List;
|
||||
|
||||
public class NumberConstantReader extends ValueReader{
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList, ExpressionsWarnHelper warnHelper){
|
||||
if(tokenList.get(0) instanceof NumberToken){
|
||||
return ConstantExpressionTemplate.of(((NumberToken)tokenList.remove(0)).getValue());
|
||||
}
|
||||
|
||||
+3
-2
@@ -25,6 +25,7 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
@@ -42,7 +43,7 @@ public class ParenthesisedExpressionReader extends ValueReader{
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList, ExpressionsWarnHelper warnHelper){
|
||||
if(tokenList.get(0) == openingParenthesis){
|
||||
int index = 0;
|
||||
int cnt = 1;
|
||||
@@ -60,7 +61,7 @@ public class ParenthesisedExpressionReader extends ValueReader{
|
||||
}
|
||||
}while(cnt != 0);
|
||||
|
||||
ExpressionTemplate result = parser.parse(new ArrayList<>(tokenList.subList(1, index)));
|
||||
ExpressionTemplate result = parser.parse(new ArrayList<>(tokenList.subList(1, index)), warnHelper);
|
||||
tokenList.subList(0, index + 1).clear();
|
||||
|
||||
return result;
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.PlaceholderToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
@@ -33,7 +34,7 @@ import java.util.List;
|
||||
|
||||
public class PlaceholderReader extends ValueReader{
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList, ExpressionsWarnHelper warnHelper){
|
||||
if(tokenList.get(0) instanceof PlaceholderToken){
|
||||
PlaceholderToken token = (PlaceholderToken)tokenList.remove(0);
|
||||
return token.getValue();
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ConstantExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.StringToken;
|
||||
@@ -34,7 +35,7 @@ import java.util.List;
|
||||
|
||||
public class StringConstantReader extends ValueReader{
|
||||
@Override
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList){
|
||||
public ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList, ExpressionsWarnHelper warnHelper){
|
||||
if(tokenList.get(0) instanceof StringToken){
|
||||
return ConstantExpressionTemplate.of(((StringToken)tokenList.remove(0)).getValue());
|
||||
}
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions.parsers;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.templates.ExpressionTemplate;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
@@ -32,5 +33,5 @@ import java.util.List;
|
||||
|
||||
public abstract class ValueReader{
|
||||
|
||||
public abstract ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList);
|
||||
public abstract ExpressionTemplate read(ExpressionTemplateParser parser, List<Token> tokenList, ExpressionsWarnHelper warnHelper);
|
||||
}
|
||||
+18
-7
@@ -33,30 +33,41 @@ import ch.andre601.advancedserverlist.core.profiles.conditions.templates.Express
|
||||
public interface Placeholder extends ExpressionTemplate{
|
||||
|
||||
static LiteralPlaceholderValue of(String value){
|
||||
return new LiteralPlaceholderValue(value);
|
||||
double doubleValue;
|
||||
try{
|
||||
doubleValue = Double.parseDouble(value);
|
||||
}catch(NumberFormatException ex){
|
||||
doubleValue = value.length();
|
||||
}
|
||||
|
||||
return new LiteralPlaceholderValue(value, doubleValue, Boolean.parseBoolean(value));
|
||||
}
|
||||
|
||||
class LiteralPlaceholderValue implements Placeholder{
|
||||
|
||||
private final String value;
|
||||
private final String stringValue;
|
||||
private final double doubleValue;
|
||||
private final boolean booleanValue;
|
||||
|
||||
public LiteralPlaceholderValue(String value){
|
||||
this.value = value;
|
||||
public LiteralPlaceholderValue(String stringValue, double doubleValue, boolean booleanValue){
|
||||
this.stringValue = stringValue;
|
||||
this.doubleValue = doubleValue;
|
||||
this.booleanValue = booleanValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToStringExpression instantiateWithStringResult(){
|
||||
return ToStringExpression.literal(value);
|
||||
return ToStringExpression.literal(stringValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToDoubleExpression instantiateWithDoubleResult(){
|
||||
return ToDoubleExpression.literal(value.length());
|
||||
return ToDoubleExpression.literal(doubleValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToBooleanExpression instantiateWithBooleanResult(){
|
||||
return ToBooleanExpression.literal(Boolean.parseBoolean(value));
|
||||
return ToBooleanExpression.literal(booleanValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -29,12 +29,13 @@ import ch.andre601.advancedserverlist.api.AdvancedServerListAPI;
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
|
||||
import java.text.ParsePosition;
|
||||
|
||||
public class PlaceholderParser{
|
||||
|
||||
public static Placeholder parse(String text, ParsePosition position, GenericPlayer player, GenericServer server){
|
||||
public static Placeholder parse(String text, ParsePosition position, GenericPlayer player, GenericServer server, ExpressionsWarnHelper warnHelper){
|
||||
AdvancedServerListAPI api = AdvancedServerListAPI.get();
|
||||
int index = position.getIndex();
|
||||
|
||||
@@ -77,6 +78,7 @@ public class PlaceholderParser{
|
||||
if(identified)
|
||||
raw.append(' ').append(valuesStr);
|
||||
|
||||
warnHelper.appendWarning(index, "Placeholder '%s' does not have a closing bracket (}).",raw.toString());
|
||||
|
||||
return Placeholder.of(raw.toString());
|
||||
}
|
||||
@@ -91,6 +93,8 @@ public class PlaceholderParser{
|
||||
|
||||
raw.append('}');
|
||||
|
||||
warnHelper.appendWarning(index, "Placeholder '%s' does not have an available PlaceholderProvider.", raw.toString());
|
||||
|
||||
return Placeholder.of(raw.toString());
|
||||
}
|
||||
|
||||
@@ -103,6 +107,8 @@ public class PlaceholderParser{
|
||||
|
||||
raw.append('}');
|
||||
|
||||
warnHelper.appendWarning(index, "Placeholder '%s' returned a null value.", raw.toString());
|
||||
|
||||
return Placeholder.of(raw.toString());
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -27,6 +27,7 @@ package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.StringToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
@@ -39,7 +40,7 @@ public class NonQuotedLiteralTokenReader extends TokenReader{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server, ExpressionsWarnHelper warnHelper){
|
||||
int startIndex = position.getIndex();
|
||||
int index = position.getIndex();
|
||||
|
||||
|
||||
+2
-1
@@ -27,6 +27,7 @@ package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.NumberToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
@@ -43,7 +44,7 @@ public class NumberTokenReader extends TokenReader{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server, ExpressionsWarnHelper warnHelper){
|
||||
int previous = position.getIndex();
|
||||
Number number = format.parse(text, position);
|
||||
|
||||
|
||||
+2
-1
@@ -27,6 +27,7 @@ package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.text.ParsePosition;
|
||||
@@ -50,7 +51,7 @@ public class PatternTokenReader extends TokenReader{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server, ExpressionsWarnHelper warnHelper){
|
||||
if(text.regionMatches(ignoreCase, position.getIndex(), pattern, 0, pattern.length())){
|
||||
position.setIndex(position.getIndex() + pattern.length());
|
||||
return token;
|
||||
|
||||
+3
-2
@@ -27,6 +27,7 @@ package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.placeholders.PlaceholderParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.PlaceholderToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
@@ -40,10 +41,10 @@ public class PlaceholderTokenReader extends TokenReader{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server, ExpressionsWarnHelper warnHelper){
|
||||
if(position.getIndex() + 1 < text.length() && text.charAt(position.getIndex()) == '$' && text.charAt(position.getIndex() + 1) == '{'){
|
||||
position.setIndex(position.getIndex() + 2);
|
||||
return new PlaceholderToken(PlaceholderParser.parse(text, position, player, server));
|
||||
return new PlaceholderToken(PlaceholderParser.parse(text, position, player, server, warnHelper));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
+2
-1
@@ -27,6 +27,7 @@ package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.StringToken;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
@@ -43,7 +44,7 @@ public class QuotedLiteralTokenReader extends TokenReader{
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server){
|
||||
public Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server, ExpressionsWarnHelper warnHelper){
|
||||
if(position.getIndex() < text.length() && text.charAt(position.getIndex()) == quote){
|
||||
int startIndex = position.getIndex();
|
||||
|
||||
|
||||
+2
-1
@@ -27,6 +27,7 @@ package ch.andre601.advancedserverlist.core.profiles.conditions.tokens.readers;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.tokens.Token;
|
||||
|
||||
import java.text.ParsePosition;
|
||||
@@ -43,5 +44,5 @@ public abstract class TokenReader{
|
||||
return priority;
|
||||
}
|
||||
|
||||
public abstract Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server);
|
||||
public abstract Token read(String text, ParsePosition position, GenericPlayer player, GenericServer server, ExpressionsWarnHelper warnHelper);
|
||||
}
|
||||
+116
-94
@@ -26,145 +26,167 @@
|
||||
package ch.andre601.advancedserverlist.core.profiles.favicon;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
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.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class FaviconHandler<F>{
|
||||
|
||||
private final Cache<String, CompletableFuture<F>> favicons = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(5, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
private final AdvancedServerList<F> core;
|
||||
private final PluginLogger logger;
|
||||
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();
|
||||
|
||||
public FaviconHandler(AdvancedServerList<F> core){
|
||||
this.core = core;
|
||||
this.logger = core.getPlugin().getPluginLogger();
|
||||
this.faviconThreadPool = createFaviconThreadPool();
|
||||
this.faviconCache = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(core.getFileHandler().getLong(1, 1, "faviconCacheTime"), TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
loadLocalFavicons();
|
||||
}
|
||||
|
||||
public F getFavicon(String input, Function<BufferedImage, F> function){
|
||||
public F getFavicon(String input){
|
||||
if(localFavicons.containsKey(input.toLowerCase(Locale.ROOT).split("\\.")[0])){
|
||||
return localFavicons.get(input.toLowerCase(Locale.ROOT).split("\\.")[0]);
|
||||
}
|
||||
|
||||
try{
|
||||
return favicons.get(input, () -> convert(input, function)).getNow(null);
|
||||
}catch(ExecutionException e){
|
||||
return faviconCache.get(input, () -> getFuture(input)).getNow(null);
|
||||
}catch(ExecutionException ex){
|
||||
logger.warn("Received ExecutionException while retrieving Favicon for '%s'.", ex, input);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void clearCache(){
|
||||
favicons.invalidateAll();
|
||||
public void cleanCache(){
|
||||
faviconCache.invalidateAll();
|
||||
loadLocalFavicons();
|
||||
}
|
||||
|
||||
private CompletableFuture<F> convert(String input, Function<BufferedImage, F> function){
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Getting BufferedImage for input '%s'...", input);
|
||||
|
||||
BufferedImage img = resolveImage(core, input);
|
||||
if(img == null){
|
||||
core.getPlugin().getPluginLogger().debugWarn(FaviconHandler.class, "No BufferedImage could be created!");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Received BufferedImage! Applying it...");
|
||||
|
||||
return function.apply(img);
|
||||
}, faviconThreadPool);
|
||||
}
|
||||
|
||||
private BufferedImage resolveImage(AdvancedServerList<F> core, String input){
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resolving favicon for input '%s'...", input);
|
||||
|
||||
InputStream stream;
|
||||
|
||||
private CompletableFuture<F> getFuture(String input){
|
||||
if(input.toLowerCase(Locale.ROOT).startsWith("https://")){
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "URL detected. Getting file from it...");
|
||||
|
||||
stream = getFromUrl(core, input);
|
||||
logger.debug(FaviconHandler.class, "Resolving URL '%s'...", input);
|
||||
return CompletableFuture.supplyAsync(() -> fromURL(core, input), this.faviconThreadPool);
|
||||
}else
|
||||
if(input.toLowerCase(Locale.ROOT).endsWith(".png")){
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Image file detected. Trying to reolve it...");
|
||||
|
||||
File folder = core.getPlugin().getFolderPath().resolve("favicons").toFile();
|
||||
if(!folder.exists()){
|
||||
core.getPlugin().getPluginLogger().warn("Cannot get Favicon %s from favicons folder. Folder doesn't exist!", input);
|
||||
return null;
|
||||
}
|
||||
|
||||
File file = new File(folder, input);
|
||||
|
||||
try{
|
||||
stream = new FileInputStream(file);
|
||||
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resolved image file!");
|
||||
}catch(IOException ex){
|
||||
core.getPlugin().getPluginLogger().warn("Cannot create Favicon from File %s.", input);
|
||||
core.getPlugin().getPluginLogger().warn("Cause: %s", ex.getMessage());
|
||||
return null;
|
||||
}
|
||||
logger.debug(FaviconHandler.class, "Resolving image file '%s'...", input);
|
||||
return CompletableFuture.completedFuture(localFavicons.get(input.toLowerCase(Locale.ROOT).split("\\.")[0]));
|
||||
}else{
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Possible player name/UUID detected. Using https://mc-heads.net/avatar/%s/64...", input);
|
||||
|
||||
stream = getFromUrl(core, "https://mc-heads.net/avatar/" + input + "/64");
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadLocalFavicons(){
|
||||
this.localFavicons.clear();
|
||||
|
||||
logger.info("Loading local image files as Favicons...");
|
||||
|
||||
Path folder = core.getPlugin().getFolderPath().resolve("favicons");
|
||||
if(!Files.exists(folder)){
|
||||
try{
|
||||
Files.createDirectories(folder);
|
||||
logger.info("Created favicons folder.");
|
||||
}catch(IOException ex){
|
||||
logger.warn("Cannot create favicons folder. Encountered an IOException.", ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(stream == null){
|
||||
core.getPlugin().getPluginLogger().warn("Cannot create Favicon. InputStream was null.");
|
||||
return null;
|
||||
try(Stream<Path> pathStream = Files.list(folder)){
|
||||
pathStream.filter(Files::isRegularFile)
|
||||
.filter(file -> file.getFileName().toString().endsWith(".png"))
|
||||
.forEach(this::loadFile);
|
||||
}catch(IOException ex){
|
||||
logger.warn("Cannot load files from Favicons folder.", ex);
|
||||
}
|
||||
|
||||
try{
|
||||
BufferedImage original = ImageIO.read(stream);
|
||||
if(original == null){
|
||||
core.getPlugin().getPluginLogger().warn("Cannot create Favicon. Unable to create BufferedImage.");
|
||||
return null;
|
||||
}
|
||||
|
||||
private void loadFile(Path path){
|
||||
try(InputStream stream = Files.newInputStream(path)){
|
||||
F favicon = createFavicon(stream);
|
||||
if(favicon == null){
|
||||
logger.warn("Cannot create Favicon from file '%s'. Received Favicon was null.", path.getFileName().toString());
|
||||
return;
|
||||
}
|
||||
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resizing image to 64x64 pixels...");
|
||||
|
||||
BufferedImage favicon = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D img = favicon.createGraphics();
|
||||
|
||||
// Resize original image to 64x64 and apply to favicon.
|
||||
img.drawImage(original, 0, 0, 64, 64, null);
|
||||
img.dispose();
|
||||
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Image resized!");
|
||||
return favicon;
|
||||
localFavicons.put(path.getFileName().toString().split("\\.")[0], favicon);
|
||||
logger.info("Loaded file '%s' as Favicon.", path.getFileName().toString());
|
||||
}catch(IOException ex){
|
||||
core.getPlugin().getPluginLogger().warn("Unable to create Favicon. Encountered IOException during creation.");
|
||||
core.getPlugin().getPluginLogger().warn("Cause: %s", ex.getMessage());
|
||||
logger.warn("Cannot create Favicon from file '%s'. Encountered IOException.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private F fromURL(AdvancedServerList<F> core, String url){
|
||||
try{
|
||||
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();
|
||||
|
||||
try(InputStream stream = client.send(request, HttpResponse.BodyHandlers.ofInputStream()).body()){
|
||||
return createFavicon(stream);
|
||||
}catch(InterruptedException | IOException ex){
|
||||
logger.warn("Cannot create Favicon from URL '%s'. Encountered an Exception.", ex, url);
|
||||
return null;
|
||||
}
|
||||
}catch(URISyntaxException ex){
|
||||
logger.warn("Cannot create Favicon from URL '%s'. Encountered an IOException.", ex, url);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream getFromUrl(AdvancedServerList<F> core, String url){
|
||||
private F createFavicon(InputStream stream){
|
||||
try{
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "Resolving URL '%s'...", url);
|
||||
logger.debug(FaviconHandler.class, "Creating BufferedImage from InputStream...");
|
||||
BufferedImage original = ImageIO.read(stream);
|
||||
if(original == null){
|
||||
logger.warn("Cannot create Favicon. Received null BufferedImage.");
|
||||
return null;
|
||||
}
|
||||
|
||||
URL faviconUrl = new URL(url);
|
||||
URLConnection connection = faviconUrl.openConnection();
|
||||
connection.setRequestProperty("User-Agent", "AdvancedServerList/" + core.getVersion());
|
||||
connection.connect();
|
||||
// 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);
|
||||
}
|
||||
|
||||
core.getPlugin().getPluginLogger().debug(FaviconHandler.class, "URL resolved!");
|
||||
return connection.getInputStream();
|
||||
}catch(IOException ex){
|
||||
core.getPlugin().getPluginLogger().warn("Error while connecting to %s for Favicon creation.", url);
|
||||
core.getPlugin().getPluginLogger().warn("Cause: %s", ex.getMessage());
|
||||
logger.debug(FaviconHandler.class, "Resizing image to 64x64 pixels...");
|
||||
BufferedImage image = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D graphics2D = image.createGraphics();
|
||||
|
||||
graphics2D.drawImage(original, 0, 0, 64, 64, null);
|
||||
graphics2D.dispose();
|
||||
|
||||
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);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -38,7 +38,9 @@ import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerHandler{
|
||||
|
||||
|
||||
+2
-2
@@ -28,9 +28,9 @@ package ch.andre601.advancedserverlist.core.profiles.profile;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.objects.NullBool;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ProfileManager{
|
||||
*/
|
||||
public static ProfileEntry merge(ServerListProfile profile){
|
||||
ProfileEntry entry = profile.getRandomProfile();
|
||||
ProfileEntry defEntry = profile.getDefaultProfile();
|
||||
ProfileEntry defEntry = profile.defaultProfile();
|
||||
|
||||
List<String> motd = resolveMOTD(entry, defEntry);
|
||||
List<String> players = resolvePlayers(entry, defEntry);
|
||||
|
||||
+1
-1
@@ -25,11 +25,11 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.profile;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
|
||||
@@ -42,6 +42,14 @@ checkUpdates: true
|
||||
#
|
||||
debug: false
|
||||
|
||||
#
|
||||
# Sets the time in minutes for favicons to be cached.
|
||||
# The number cannot be less than 1.
|
||||
#
|
||||
# Defaults to 1 if not set.
|
||||
#
|
||||
faviconCacheTime: 1
|
||||
|
||||
#
|
||||
# DO NOT EDIT!
|
||||
#
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
package ch.andre601.advancedserverlist.test;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionEngine;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.expressions.ExpressionsWarnHelper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -43,7 +44,8 @@ public class ExpressionParserTests{
|
||||
for(Map.Entry<String, Boolean> values : testValuesMap.entrySet()){
|
||||
logger.info("TEST[expression=\"%s\", expected=%b]", values.getKey(), values.getValue());
|
||||
|
||||
boolean result = expressionEngine.compile(values.getKey(), logger, null, null).instantiateWithBooleanResult().evaluate();
|
||||
ExpressionsWarnHelper warnHelper = new ExpressionsWarnHelper(values.getKey());
|
||||
boolean result = expressionEngine.compile(values.getKey(), null, null, warnHelper).instantiateWithBooleanResult().evaluate();
|
||||
logger.info("Result (output, isExpected): " + result + ", " + (result == values.getValue()));
|
||||
assertEquals(result, values.getValue());
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import posixpath
|
||||
import re
|
||||
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
@@ -39,9 +38,6 @@ def on_page_markdown(
|
||||
elif type == "deprecated": return _admo(text = args, type = "deprecated")
|
||||
else: return _admo(text = args)
|
||||
|
||||
# Otherwise, raise an error
|
||||
raise RuntimeError(f"Unknown shortcode: {type}")
|
||||
|
||||
# Find and replace all external asset URLs in current page
|
||||
return re.sub(
|
||||
r"<!-- admo:(\w+)(.*?) -->",
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#
|
||||
# A simple hook that replaces any appearances of \| with just |.
|
||||
#
|
||||
# There is an inconsistency between GitHub flavourited Markdown and Python Markdown
|
||||
# where the former treats | as part of a table, even if it is inside inline code
|
||||
# causing unwanted table rendering.
|
||||
#
|
||||
# The only way to prevent this is to escape it by prefixing it with a back slash (\).
|
||||
# Unfortunately does this cause issues on Python-Markdown, as it renders inline code
|
||||
# content as-is without special treatments whatsoever, meaning that `\|` will be
|
||||
# rendered as <code>\|</code> in the end.
|
||||
#
|
||||
# Using this hook, `\|` is being turned into `|` before further processing, resulting
|
||||
# in <code>|</code> being rendered in the end, while preserving proper table rendering
|
||||
# on GitHub and co.
|
||||
#
|
||||
import re
|
||||
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
from mkdocs.structure.files import File, Files
|
||||
from mkdocs.structure.pages import Page
|
||||
|
||||
def on_page_markdown(
|
||||
markdown: str, *, page: Page, config: MkDocsConfig, files: Files
|
||||
):
|
||||
return re.sub(r"\\\|","|",markdown)
|
||||
+2
-1
@@ -6,4 +6,5 @@ nav:
|
||||
- examples
|
||||
- migration
|
||||
- api
|
||||
- PlaceholderAPI: placeholderapi
|
||||
- addons
|
||||
- PlaceholderAPI: placeholderapi
|
||||
@@ -0,0 +1,44 @@
|
||||
# BanPlugins Addon
|
||||
|
||||
The BanPlugins Addon was made to provide placeholders for different punishment plugins to use in AdvancedServerList.
|
||||
|
||||
## Placeholders
|
||||
|
||||
### AdvancedBan
|
||||
|
||||
Placeholders for the plugin [AdvancedBan](https://www.spigotmc.org/resources/8695/){ target="_blank" rel="nofollow" } are available to use.
|
||||
|
||||
| Placeholder | Description |
|
||||
|---------------------------------|-------------------------------------------------------------------------------------------|
|
||||
| `${advancedban isMuted}` | Whether the player is muted or not. |
|
||||
| `${advancedban muteReason}` | The reason for why the player was muted. Returns invalid placeholder if no mute was set. |
|
||||
| `${advancedban muteDuration}` | Relative time until the mute expires.[^1] Returns invalid placeholder if no mute was set. |
|
||||
| `${advancedban muteExpiration}` | Date on when the mute will expire.[^2] |
|
||||
| `${advancedban isBanned}` | Whether the player is banned or not. |
|
||||
| `${advancedban banReason}` | The reason for why the player was banned. Returns invalid placeholder if no ban was set. |
|
||||
| `${advancedban banDuration}` | Relative time until the ban expires.[^3] Returns invalid placeholder if no ban was set. |
|
||||
| `${advancedban banExpiration}` | Date on when the ban will expire.[^4] |
|
||||
|
||||
[^1]:
|
||||
An optional boolean can be added to set whether the duration should be from the start or not. `false` is the default.
|
||||
Example: `${advancedban muteDuration true}`
|
||||
[^2]:
|
||||
An optional Date and time Pattern can be set to change the displayed output. The default is `dd, MMM yyyy HH:mm:ss`.
|
||||
Example: `${advancedban muteExpiration yyyy-MM-dd HH:mm:ss}`
|
||||
[^3]:
|
||||
An optional boolean can be added to set whether the duration should be from the start or not. `false` is the default.
|
||||
Example: `${advancedban banDuration true}`
|
||||
[^4]:
|
||||
An optional Date and time Pattern can be set to change the displayed output. The default is `dd, MMM yyyy HH:mm:ss`.
|
||||
Example: `${advancedban banExpiration yyyy-MM-dd HH:mm:ss}`
|
||||
|
||||
## Example
|
||||
|
||||
```yaml title="banned.yml"
|
||||
priority: 1
|
||||
condition: '${advancedban isBanned}'
|
||||
|
||||
motd:
|
||||
- '<red>You were <bold>BANNED</bold>!'
|
||||
- '<red>Expires: <grey>${advancedban banExpiration}'
|
||||
```
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
icon: octicons/plus-circle-24
|
||||
---
|
||||
|
||||
# Addons
|
||||
|
||||
This section contains a curated list of add-ons for AdvancedServerList which can be used to enhance the plugin in different ways.
|
||||
Do you have a plugin that hooks into AdvancedServerList that is not listed here? Contact Andre601 on Discord and it will be added!
|
||||
|
||||
## First-party Addons
|
||||
|
||||
These Addons are made by Andre601 and available together with the plugin downloads.
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- [**BanPlugins**](banplugins.md)
|
||||
|
||||
----
|
||||
|
||||
Addon for different Punishment plugins such as AdvancedBan, that add new placeholders to use in AdvancedServerList.
|
||||
|
||||
</div>
|
||||
|
||||
## Third-party
|
||||
|
||||
Third-party addons made by other people not working on AdvancedServerList.
|
||||
|
||||
*Currently no entries*
|
||||
@@ -40,7 +40,7 @@ document$.subscribe(async () => {
|
||||
const versionToken = '{version}'
|
||||
const entries = document.querySelectorAll('.md-content code');
|
||||
for(const entry of entries) {
|
||||
entry.innerHTML = entry.innerHTML.replace(new RegExp(versionToken, 'g'), version);
|
||||
entry.innerHTML = entry.innerHTML.replace(new RegExp(versionToken, 'g'), version.substring(1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+25
-4
@@ -17,7 +17,9 @@ Feel free to suggest additional examples on my [Discord Server](https://discord.
|
||||
- [Versions](#versions)
|
||||
- [Different List for outdated Clients](#different-list-for-outdated-clients)
|
||||
- [Different MOTD for < 1.16](#different-motd-for-116)
|
||||
- [Spigot/PaperMC](#spigotpapermc)
|
||||
- [BungeeCord/Velocity](#bungeecordvelocity)
|
||||
- [Display MOTD for a set of subdomains](#display-motd-for-a-set-of-subdomains)
|
||||
- [PaperMC](#papermc)
|
||||
- [Different profile for banned Player](#different-profile-for-banned-player)
|
||||
- [Other](#other)
|
||||
- [Different profile for different host](#different-profile-for-different-host)
|
||||
@@ -64,9 +66,28 @@ motd:
|
||||
```
|
||||
|
||||
----
|
||||
## Spigot/PaperMC
|
||||
## BungeeCord/Velocity
|
||||
|
||||
Examples that can be used with the Spigot or PaperMC version.
|
||||
Examples usable on the BungeeCord and Velocity version.
|
||||
|
||||
### Display MOTD for a set of subdomains
|
||||
|
||||
Displays the same MOTDs for the server when pinged on any sub-domain starting with `lobby` (i.e. `lobby-1.example.com`).
|
||||
|
||||
```yaml title="lobby-motd.yml"
|
||||
priority: 1
|
||||
|
||||
condition: '${server host} |- "lobby"'
|
||||
|
||||
motd:
|
||||
- '<green>Lobby Server'
|
||||
- '<grey>Example Server'
|
||||
```
|
||||
|
||||
----
|
||||
## PaperMC
|
||||
|
||||
Examples that can be used with the PaperMC version.
|
||||
|
||||
### Different profile for banned Player
|
||||
|
||||
@@ -114,7 +135,7 @@ Display a different profile, if the player pinging the server is "known" by Adva
|
||||
```yaml title="personalized.yml"
|
||||
priority: 1
|
||||
|
||||
condition: '${player name} != Anonymous' # "Anonymous" would be the value from the "unknownPlayer > name" option.
|
||||
condition: '${player name} != "Anonymous"' # "Anonymous" would be the value from the "unknownPlayer > name" option.
|
||||
|
||||
motd:
|
||||
- '<grey>Hello there <aqua>${player name}</aqua>!'
|
||||
|
||||
@@ -9,19 +9,40 @@ It tries to be an easy to understand as possible. But if you still have problems
|
||||
|
||||
## 1. Download the plugin { #download-the-plugin }
|
||||
|
||||
The first step would be to download the plugin from a download page of your choice. As of writing this is AdvancedServerList updated and available on these sites:
|
||||
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!):
|
||||
|
||||
- [Modrinth]
|
||||
- [Codeberg]
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- [:simple-modrinth: **Modrinth**][modrinth]
|
||||
|
||||
----
|
||||
|
||||
:octicons-check-24:{ style="color: var(--md-badge-fg--success);" } **Actively updated!**
|
||||
|
||||
- [:simple-codeberg: **Codeberg**][codeberg]
|
||||
|
||||
----
|
||||
|
||||
:octicons-check-24:{ style="color: var(--md-badge-fg--success);" } **Actively updated!**
|
||||
|
||||
- [:fontawesome-solid-paper-plane: **HangarMC**][hangar]
|
||||
|
||||
----
|
||||
|
||||
:octicons-check-24:{ style="color: var(--md-badge-fg--success);" } **Actively updated!**
|
||||
|
||||
|
||||
- [:simple-spigotmc: **SpigotMC**][spigot]
|
||||
|
||||
----
|
||||
|
||||
:octicons-alert-24:{ style="color: var(--md-badge-fg--warning);" } **Discontinued!**
|
||||
|
||||
</div>
|
||||
|
||||
[modrinth]: https://modrinth.com/plugin/advancedserverlist
|
||||
[codeberg]: https://codeberg.org/Andre601/AdvancedServerList
|
||||
|
||||
The plugin is also available on these platforms, but not actively updated there anymore:
|
||||
|
||||
- [Spigot] (Latest version: `3.3.0-b1`)
|
||||
- [Hangar] (Latest version: `3.5.0`)
|
||||
|
||||
[spigot]: https://www.spigotmc.org/resources/102910/
|
||||
[hangar]: https://hangar.papermc.io/Andre_601/AdvancedServerList
|
||||
|
||||
@@ -29,10 +50,44 @@ The plugin is available for Paper, BungeeCord, Waterfall and Velocity, and has b
|
||||
|
||||
The plugin also supports these additional plugins. They are all optional.
|
||||
|
||||
- [PlaceholderAPI] - Used on the Spigot and Paper server for additional Placeholder parsing.
|
||||
- [ViaVersion] - Used on the Paper server for additional protocol version handling.
|
||||
- [PAPIProxyBridge] - Used on BungeeCord, Waterfall and Velocity for PlaceholderAPI support.
|
||||
- [Maintenance] - Used to disable server list handling while maintenance is active.
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- [**PlaceholderAPI**][placeholderapi]
|
||||
|
||||
----
|
||||
|
||||
Supported on:
|
||||
|
||||
- :fontawesome-solid-paper-plane: Paper
|
||||
|
||||
- [**ViaVersion**][viaversion]
|
||||
|
||||
----
|
||||
|
||||
Supported on:
|
||||
|
||||
- :fontawesome-solid-paper-plane: Paper
|
||||
|
||||
- [**PAPIProxyBridge**][papiproxybridge]
|
||||
|
||||
----
|
||||
|
||||
Supported on:
|
||||
|
||||
- :simple-spigotmc: BungeeCord
|
||||
- :fontawesome-solid-paper-plane: Velocity
|
||||
|
||||
- [**Maintenance**][maintenance]
|
||||
|
||||
----
|
||||
|
||||
Supported on:
|
||||
|
||||
- :fontawesome-solid-paper-plane: Paper
|
||||
- :simple-spigotmc: BungeeCord
|
||||
- :fontawesome-solid-paper-plane: Velocity
|
||||
|
||||
</div>
|
||||
|
||||
[placeholderapi]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
|
||||
[viaversion]: https://hangar.papermc.io/ViaVersion/ViaVersion
|
||||
@@ -85,13 +140,12 @@ On first creation will the folder have a `default.yml` file. This file contains
|
||||
priority: 0
|
||||
|
||||
#
|
||||
# Set conditions that needs to be met.
|
||||
# Only when all conditions return true will the profile be shown (Given no profile with higher priority is used).
|
||||
# Set conditions that need to me met to show this profile.
|
||||
# You can use keywords 'and' or 'or' (Or alternatively '&&' or `||`) to make more complex condition sets.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#conditions
|
||||
# Read more: https://asl.andre601.ch/profiles/#condition
|
||||
#
|
||||
#conditions:
|
||||
# - '{playerVersion} < 759'
|
||||
# condition: '${player protocol} < 759'
|
||||
|
||||
#
|
||||
# Option that allows you to define multiple profiles to use.
|
||||
@@ -322,17 +376,17 @@ config-version: 2
|
||||
There are certain files and folders that get created when certain events happen:
|
||||
|
||||
- A `playercache.json` file will be created on plugin shutdown containing a list of IPs, UUIDs and Player names for every player that joined the server while AdvancedServerList was running.
|
||||
This file allows to replace `${player name}` and `${player uuid}` with their name or UUID respectively, while they are not on the server, by using the IP they used to join with.
|
||||
This file is not created nor updated when `disableCache` is set to `true` in the config.yml
|
||||
This file allows to replace `${player name}` and `${player uuid}` with their name or UUID respectively, while they are not on the server, by using the IP they used to join with.
|
||||
This file is not created nor updated when `disableCache` is set to `true` in the config.yml
|
||||
- A `backups` folder containing old config.yml files.
|
||||
This folder is created when AdvancedServerList migrates your old config to a new version. This allows you to transfer settings over in case the migration didn't work properly.
|
||||
This folder is created when AdvancedServerList migrates your old config to a new version. This allows you to transfer settings over in case the migration didn't work properly.
|
||||
|
||||
## 3. Creating your first profile { #creating-your-first-profile }
|
||||
|
||||
Creating your first profile is relatively simple.
|
||||
|
||||
To start, open the `default.yml` file located inside the `profiles` folder using a file editor of your choice (VSCode or Notepad++ are recommended). It should contain all the available options for a server list profile.
|
||||
Next can you edit the options available to whatever you like. All text options (Except [conditions](../profiles/index.md#conditions)) support [MiniMessage formatting](../profiles/formatting.md).
|
||||
Next can you edit the options available to whatever you like. All text options (Except [condition](../profiles/index.md#condition)) support [MiniMessage formatting](../profiles/formatting.md).
|
||||
|
||||
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.
|
||||
@@ -351,16 +405,20 @@ motd:
|
||||
To add additional profiles, create a new YAML file inside the `profiles` folder. The name doesn't matter, but it is recommended to keep it lowercase, use alphanumeric characters (`a-z, 0-9`), hyphens (`-`), underscores (`_`) and avoid spaces.
|
||||
|
||||
Inside the file, add a priority and at least one setting, similar to the above shown example.
|
||||
This would already be enough and AdvancedServerList would use it. If you however want to only show it when certain conditions are met, should you set the priority to a higher value and add conditions.
|
||||
This would already be enough to have a valid profile, but depending on the priority and file name may the file not be used, or used over other profiles.
|
||||
|
||||
Conditions can be multiple strings containing [operands](../profiles/index.md#operands) to evaluate them. As an example `${server playersOnline} >= 10` would return true if the current number of online players is larger or equal to 10.
|
||||
If you want to only show this file under specific situations can you use the [`condition`](../profiles/index.md#condition) option to apply conditions that need to be met to show the profile.
|
||||
The condition option would have a single String containing one or muliple [Expressions](../profiles/expressions.md). Only if the condition would return true, would the profile be displayed, granted that it has a higher priority than any other valid file with a true condition output.
|
||||
|
||||
Here is another example profile using conditions:
|
||||
/// info | Note
|
||||
Profiles which do not have any conditions, or have an empty condition, will always considered to have a true condition, meaning that a profile with higher priority and no condition will be selected over a profile with lower priority and a condition, even if said condition returns true.
|
||||
///
|
||||
|
||||
Here is another example profile using conditions to show it when the player was banned on the server:
|
||||
```yaml title="other_profile.yml"
|
||||
priority: 1
|
||||
|
||||
conditions:
|
||||
- '${player isBanned} = true'
|
||||
condition: '${player isBanned}'
|
||||
|
||||
motd:
|
||||
- '<red>You got <bold>banned</bold> from this server.'
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
nav:
|
||||
- index.md
|
||||
- v3_8_0-to-v3_9_0.md
|
||||
- v3_7_0-to-v3_8_0.md
|
||||
- pre-v3_7_0-to-v3_7_0.md
|
||||
- v1_9_0-to-v1_10_0.md
|
||||
- v1_5_3-to-v1_6_0.md
|
||||
+27
-1
@@ -10,4 +10,30 @@ Note that these pages only cover server list profile files. The config.yml is au
|
||||
|
||||
## Pages
|
||||
|
||||
{nav}
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- [**v3.7.0 to v3.8.0**](v3_7_0-to-v3_8_0.md)
|
||||
|
||||
----
|
||||
|
||||
Migrating from version 3.7.0 to 3.8.0.
|
||||
|
||||
- [**< v3.7.0 to v3.7.0**](pre-v3_7_0-to-v3_7_0.md)
|
||||
|
||||
----
|
||||
|
||||
Migrate from any version prior to 3.7.0 to 3.7.0 or newer.
|
||||
|
||||
- [**v1.9.0 to v1.10.0**](v1_9_0-to-v1_10_0.md)
|
||||
|
||||
----
|
||||
|
||||
Migrate from version 1.9.0 to 1.10.0.
|
||||
|
||||
- [**v1.5.3 to v1.6.0**](v1_5_3-to-v1_6_0.md)
|
||||
|
||||
----
|
||||
|
||||
Migrate from version 1.5.3 to 1.6.0.
|
||||
|
||||
</div>
|
||||
@@ -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.
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
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
|
||||
|
||||
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}!'
|
||||
```
|
||||
///
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
icon: octicons/arrow-right-24
|
||||
---
|
||||
|
||||
# v3.8.0 to v3.9.0
|
||||
|
||||
v3.9.0 brings a small change to the `~=` operand by changing it to `=~` for sake of consistent pattern design. Additionally, was `~` added as a single-character equivalent to `=`.
|
||||
|
||||
## Migration
|
||||
|
||||
To migrate, switch any appearances of `~=` with `=~` or `~`.
|
||||
|
||||
## Example
|
||||
|
||||
Here is a before and after example to help visualize the change:
|
||||
|
||||
/// tab | Before
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
conditions: '${player name} ~= "Someone"'
|
||||
|
||||
motd:
|
||||
- 'Welcome ${player name}!'
|
||||
```
|
||||
///
|
||||
|
||||
/// tab | After
|
||||
```yaml
|
||||
priority: 0
|
||||
|
||||
condition: '${player name} =~ "Someone"'
|
||||
|
||||
motd:
|
||||
- 'Welcome ${player name}!'
|
||||
```
|
||||
///
|
||||
|
||||
/// tab | Diff View
|
||||
```diff
|
||||
priority: 0
|
||||
|
||||
-condition: '${player name} ~= "Someone"'
|
||||
+condition: '${player name} =~ "Someone"'
|
||||
|
||||
motd:
|
||||
- 'Welcome ${player name}!'
|
||||
```
|
||||
///
|
||||
@@ -32,12 +32,14 @@ The following cases are considered literal values:
|
||||
|
||||
Any number is considered an expression, meaning the below examples are considered valid:
|
||||
|
||||
/// example | Examples
|
||||
```
|
||||
0
|
||||
1000
|
||||
-7
|
||||
47.2
|
||||
```
|
||||
///
|
||||
|
||||
#### Strings
|
||||
|
||||
@@ -50,10 +52,12 @@ As an example, `Sand` would cause the expression engine to see `S AND` due to pa
|
||||
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.
|
||||
///
|
||||
|
||||
/// example | Examples
|
||||
```
|
||||
"Hello World!"
|
||||
""
|
||||
```
|
||||
///
|
||||
|
||||
#### Booleans
|
||||
|
||||
@@ -63,6 +67,7 @@ Strings `true` and `false` are treated as boolean literals.
|
||||
|
||||
Any [placeholder](placeholders.md) is a valid expression.
|
||||
|
||||
/// example | Examples
|
||||
```
|
||||
${player protocol}
|
||||
${player name}
|
||||
@@ -70,6 +75,7 @@ ${player name}
|
||||
${server playersOnline}
|
||||
${server host}
|
||||
```
|
||||
///
|
||||
|
||||
### Binary Operators
|
||||
|
||||
@@ -77,23 +83,23 @@ ${server host}
|
||||
|
||||
The following binary operators can be used for boolean evaluation:
|
||||
|
||||
| Operator | True if |
|
||||
|----------------------------------|-------------------------------------------------------------------------------------------------------------|
|
||||
| `and` / `&&` | Both expressions return true. |
|
||||
| `or` / <code>||</code> | Either expression returns true. |
|
||||
| `==` / `=` | Both expressions are equal (Case sensitive). |
|
||||
| `~=` | Both expressions are equal (Not Case sensitive). |
|
||||
| `!=` | Both expressions are not equal (Case sensitive). |
|
||||
| `!~` | Both expressions are not equal (Not case sensitive). |
|
||||
| <code>|-</code> | Left expression starts with right expression. |
|
||||
| <code>-|</code> | Left expression ends with right expression. |
|
||||
| `<-` | Left expression contains right expression. |
|
||||
| `<` | Left expression is less than the right expression. Strings use their text length as number. |
|
||||
| `<=` | Left expression is less than, or equal to, the right expression. Strings use their text length as number. |
|
||||
| `>` | Left expression is larger than the right expression. Strings use their text length as number. |
|
||||
| `>=` | Left expression is larger than, or equal to, the right expression. Strings use their text length as number. |
|
||||
| Operator | True if |
|
||||
|---------------|-------------------------------------------------------------------------------------------------------------|
|
||||
| `and` / `&&` | Both expressions return true. |
|
||||
| `or` / `\|\|` | 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). |
|
||||
| `\|-` | Left expression starts with right expression. |
|
||||
| `-\|` | 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:
|
||||
These additional binary operators can also be used to perform certain actions:
|
||||
|
||||
| Operator | Semantic |
|
||||
|----------|-----------------------------------------------------------------------------|
|
||||
@@ -103,10 +109,17 @@ Additionally can these additional binary operators used for specific actions:
|
||||
| `*` | Multiplies two numbers. Strings use their text length as number. |
|
||||
| `/` | Divides one number by another. Strings use their text length as number. |
|
||||
|
||||
/// example | Examples
|
||||
```
|
||||
${player name} != "Anonymous"
|
||||
763 > ${player protocol} > 758
|
||||
${player hasPlayedBefore} and ${player isBanned} == "false"
|
||||
```
|
||||
///
|
||||
|
||||
### Parenthesis
|
||||
|
||||
`( <expression> )` is a valid expression.
|
||||
|
||||
Parenthesis can be used to prevent ambiguities.
|
||||
|
||||
### Negation
|
||||
@@ -119,5 +132,4 @@ Parenthesis can be used to prevent ambiguities.
|
||||
|
||||
## 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
|
||||
This page, including some examples used, was adobted from [:octicons-book-24: CodeCrafter47/BungeeTabListPlus/wiki](https://github.com/CodeCrafter47/BungeeTabListPlus/wiki/Expressions){ target="_blank" rel="nofollow" }.
|
||||
@@ -38,8 +38,18 @@ The following options are **not** supported, no matter what option they are used
|
||||
|
||||
## Colors
|
||||
|
||||
Color options (`<aqua>`, `<red>`, `<gray>`, etc.) are available for all text options.
|
||||
24-Bit HEX colors (`<#ff0000>`, `<#123abc>`, etc.) are only available for the [`Motd` option](../index.md#motd) for a 1.16+ Server/Proxy.
|
||||
### Default colors
|
||||
|
||||
Default colors such as `<red>`, `<green>`, `<aqua>`, etc. may be used in all text options.
|
||||
|
||||
### Hex Colors
|
||||
|
||||
Hexadecimal colors may be used in the [`motd`](index.md#motd) option using the `<#RRGGBB>` format.
|
||||
|
||||
### Gradients
|
||||
|
||||
Gradients can be created by using `<gradient:<color1>:<color2>>`, replacing `<color1>` with a starting color name or hex color value and `<color2>` with an ending color name or hex color value.
|
||||
Only the [`motd`](index.md#motd) option may support hex color gradients and in all other options will it be downsampled.
|
||||
|
||||
## Formatting
|
||||
|
||||
|
||||
@@ -40,33 +40,6 @@ Not setting this option, or setting it to an empty String (`condition: ''`), wil
|
||||
|
||||
The condition option can hold one or multiple expressions. The Expression system is explained on the [Expressions page](expressions.md).
|
||||
|
||||
## Conditions :octicons-trash-24:{ style="color: #FF5252;" title="Deprecated" }
|
||||
|
||||
<!-- admo:deprecated Deprecated in favour of the new condition option. Will be removed in a future version. -->
|
||||
|
||||
The `conditions` option - not to be confused with the new [`condition`](#condition) option - allows you to define one or multiple conditions/expressions that all need to return `true` in order for the profile to be used.
|
||||
Not setting this option, or setting it to an empty list (`conditions: []`), will result in `true` being returned.
|
||||
|
||||
Each condition can use [placeholders](placeholders.md) to further customize it. PlaceholderAPI placeholders are **not** supported!
|
||||
|
||||
### Operands
|
||||
|
||||
<!-- admo:warning Each condition can only hold one operand -->
|
||||
|
||||
Each condition can use operands to compare values with each other.
|
||||
Note that if Operands are used that compare sizes (i.e. `>`) while the values are Text and not numbers will the text length be used as number.
|
||||
|
||||
| Operand | 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
|
||||
|
||||
The `profile` option allows you to define a list of all other options, with the exception of [`priority`](#priority), [`condition`](#condition) or itself.
|
||||
|
||||
@@ -106,3 +106,4 @@ markdown_extensions:
|
||||
|
||||
hooks:
|
||||
- docs/.hooks/badges.py
|
||||
- docs/.hooks/replacer.py
|
||||
+1
-9
@@ -48,14 +48,6 @@
|
||||
<id>papermc</id>
|
||||
<url>https://papermc.io/repo/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spigot</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>protocollib-repo</id>
|
||||
<url>https://repo.dmulloy2.net/repository/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>placeholderapi-repo</id>
|
||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||
@@ -125,7 +117,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<version>3.5.2</version>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<relocations>
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.CachedServerIcon;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon>{
|
||||
@@ -107,12 +108,17 @@ public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFaviconHandler(AdvancedServerList<CachedServerIcon> core){
|
||||
faviconHandler = new FaviconHandler<>(core);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearFaviconCache(){
|
||||
if(faviconHandler == null)
|
||||
return;
|
||||
|
||||
faviconHandler.clearCache();
|
||||
faviconHandler.cleanCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,6 +159,11 @@ public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon
|
||||
return "paper";
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedServerIcon createFavicon(BufferedImage image) throws Exception{
|
||||
return Bukkit.loadServerIcon(image);
|
||||
}
|
||||
|
||||
public WorldCache getWorldCache(){
|
||||
if(worldCache != null)
|
||||
return worldCache;
|
||||
@@ -171,11 +182,11 @@ public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon
|
||||
getPluginLogger().warn(" - Reliance on a different plugin for core functionalities.");
|
||||
getPluginLogger().warn(" - Bad dependency loading limited to MavenCentral only.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("Please consider switching to Paper or one of the Paper-compatible forks to benefit from");
|
||||
getPluginLogger().warn("overall performance improvements amongst other things.");
|
||||
getPluginLogger().warn("Please consider switching to Paper or one of the Paper-compatible forks to benefit");
|
||||
getPluginLogger().warn("from overall performance improvements amongst other things.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("AdvancedServerList will now disable itself. If you believe this was a mistake, report");
|
||||
getPluginLogger().warn("this on Codeberg: https://codeberg.org/Andre601/AdvancedServerList");
|
||||
getPluginLogger().warn("Disabling AdvancedServerList. If you believe this is an error, report it on");
|
||||
getPluginLogger().warn("Codeberg: https://codeberg.org/Andre601/AdvancedServerList");
|
||||
getPluginLogger().warn("======================================================================================");
|
||||
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
|
||||
+3
-7
@@ -45,8 +45,9 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.util.CachedServerIcon;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon, PaperPlayerImpl>{
|
||||
|
||||
@@ -186,9 +187,4 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
|
||||
public GenericServer createGenericServer(int playersOnline, int playersMax, String host){
|
||||
return new PaperServerImpl(plugin.getWorldCache().worlds(), playersOnline, playersMax, host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedServerIcon createFavicon(BufferedImage image) throws Exception{
|
||||
return Bukkit.loadServerIcon(image);
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.build.commit/>
|
||||
|
||||
<plugin.version>3.7.0</plugin.version>
|
||||
<plugin.version>4.1.0</plugin.version>
|
||||
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
|
||||
|
||||
<api.version>v3.1.0</api.version>
|
||||
@@ -60,5 +60,6 @@
|
||||
<module>paper</module>
|
||||
<module>velocity</module>
|
||||
<module>version-uploader</module>
|
||||
<module>addons/banplugins</module>
|
||||
</modules>
|
||||
</project>
|
||||
+2
-1
@@ -12,7 +12,8 @@
|
||||
"ch.andre601.asl-api:platform-bukkit",
|
||||
"ch.andre601.asl-api:platform-bungeecord",
|
||||
"ch.andre601.asl-api:platform-velocity",
|
||||
"ch.andre601.asl-api:api"
|
||||
"ch.andre601.asl-api:api",
|
||||
"com.github.DevLeoko:AdvancedBan"
|
||||
],
|
||||
"registryUrls": [
|
||||
"https://jitpack.io"
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
mkdocs-material==9.5.6
|
||||
mkdocs-material==9.5.10
|
||||
mkdocs-glightbox==0.3.7
|
||||
mkdocs-awesome-pages-plugin==2.9.2
|
||||
git+https://github.com/Andre601/mkdocs-pagenav-generator
|
||||
+1
-1
@@ -100,7 +100,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<version>3.5.2</version>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<relocations>
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.bstats.charts.SimplePie;
|
||||
import org.bstats.velocity.Metrics;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class VelocityCore implements PluginCore<Favicon>{
|
||||
@@ -101,12 +102,17 @@ public class VelocityCore implements PluginCore<Favicon>{
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFaviconHandler(AdvancedServerList<Favicon> core){
|
||||
faviconHandler = new FaviconHandler<>(core);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearFaviconCache(){
|
||||
if(faviconHandler == null)
|
||||
return;
|
||||
|
||||
faviconHandler.clearCache();
|
||||
faviconHandler.cleanCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,6 +153,11 @@ public class VelocityCore implements PluginCore<Favicon>{
|
||||
return "velocity";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Favicon createFavicon(BufferedImage image) throws Exception{
|
||||
return Favicon.create(image);
|
||||
}
|
||||
|
||||
public ProxyServer getProxy(){
|
||||
return proxy;
|
||||
}
|
||||
|
||||
-6
@@ -44,7 +44,6 @@ import com.velocitypowered.api.proxy.server.ServerPing;
|
||||
import com.velocitypowered.api.util.Favicon;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -205,9 +204,4 @@ public class VelocityEventWrapper implements GenericEventWrapper<Favicon, Veloci
|
||||
|
||||
return new VelocityProxyImpl(servers, playersOnline, playersMax, host);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Favicon createFavicon(BufferedImage image){
|
||||
return Favicon.create(image);
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.4.14</version>
|
||||
<version>1.5.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -73,6 +73,12 @@
|
||||
<version>2.0.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>club.minnced</groupId>
|
||||
<artifactId>discord-webhooks</artifactId>
|
||||
<version>0.8.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -109,7 +115,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<version>3.5.2</version>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
</configuration>
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2024 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.versionuploader;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ModrinthRelease{
|
||||
|
||||
Map<String, String> releases = new HashMap<>();
|
||||
|
||||
public void addRelease(String platform, String id){
|
||||
releases.put(platform, id);
|
||||
}
|
||||
|
||||
public Map<String, String> getReleases(){
|
||||
return releases;
|
||||
}
|
||||
}
|
||||
+16
-8
@@ -31,27 +31,35 @@ public enum PlatformInfo{
|
||||
|
||||
PAPER(
|
||||
"paper",
|
||||
"paper/target/AdvancedServerList-Paper-{{version}}.jar",
|
||||
List.of(
|
||||
"paper/target/AdvancedServerList-Paper-{{version}}.jar",
|
||||
"addons/banplugins/target/AdvancedServerList-BanPlugins-Addon-{{version}}.jar"
|
||||
),
|
||||
"paper", "folia"
|
||||
),
|
||||
BUNGEECORD(
|
||||
"bungeecord",
|
||||
"bungeecord/target/AdvancedServerList-BungeeCord-{{version}}.jar",
|
||||
List.of(
|
||||
"bungeecord/target/AdvancedServerList-BungeeCord-{{version}}.jar",
|
||||
"addons/banplugins/target/AdvancedServerList-BanPlugins-Addon-{{version}}.jar"
|
||||
),
|
||||
"bungeecord", "waterfall"
|
||||
),
|
||||
VELOCITY(
|
||||
"velocity",
|
||||
"velocity/target/AdvancedServerList-Velocity-{{version}}.jar",
|
||||
List.of(
|
||||
"velocity/target/AdvancedServerList-Velocity-{{version}}.jar"
|
||||
),
|
||||
"velocity"
|
||||
);
|
||||
|
||||
private final String platform;
|
||||
private final String filePath;
|
||||
private final List<String> filePaths;
|
||||
private final List<String> loaders;
|
||||
|
||||
PlatformInfo(String platform, String filePath, String... loaders){
|
||||
PlatformInfo(String platform, List<String> filePaths, String... loaders){
|
||||
this.platform = platform;
|
||||
this.filePath = filePath;
|
||||
this.filePaths = filePaths;
|
||||
this.loaders = List.of(loaders);
|
||||
}
|
||||
|
||||
@@ -59,8 +67,8 @@ public enum PlatformInfo{
|
||||
return platform;
|
||||
}
|
||||
|
||||
public String getFilePath(){
|
||||
return filePath;
|
||||
public List<String> getFilePaths(){
|
||||
return filePaths;
|
||||
}
|
||||
|
||||
public List<String> getLoaders(){
|
||||
|
||||
+75
-22
@@ -29,12 +29,18 @@ import ch.andre601.advancedserverlist.versionuploader.data.CodebergRelease;
|
||||
import ch.andre601.advancedserverlist.versionuploader.data.CodebergReleaseFetcher;
|
||||
import ch.andre601.advancedserverlist.versionuploader.hangar.HangarVersionUploader;
|
||||
import ch.andre601.advancedserverlist.versionuploader.modrinth.ModrinthVersionUploader;
|
||||
import club.minnced.discord.webhook.WebhookClient;
|
||||
import club.minnced.discord.webhook.WebhookClientBuilder;
|
||||
import club.minnced.discord.webhook.receive.ReadonlyMessage;
|
||||
import club.minnced.discord.webhook.send.WebhookEmbed;
|
||||
import club.minnced.discord.webhook.send.WebhookEmbedBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@@ -47,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]");
|
||||
LOGGER.warn("COMMAND USAGE: java -jar VersionUploader.jar <--all|--modrinth|--hangar> [--dryrun]");
|
||||
System.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -60,32 +66,28 @@ public class VersionUploader{
|
||||
return;
|
||||
}
|
||||
|
||||
boolean dryrun = false;
|
||||
if(args.length >= 2){
|
||||
dryrun = args[1].equalsIgnoreCase("--dryrun");
|
||||
}
|
||||
|
||||
CompletableFuture<?> future;
|
||||
ModrinthRelease modrinthRelease = null;
|
||||
switch(args[0].toLowerCase(Locale.ROOT)){
|
||||
case "--modrinth" -> future = new ModrinthVersionUploader().performUpload(release, false);
|
||||
case "--hangar" -> future = new HangarVersionUploader().performUpload(release, false);
|
||||
case "--all" -> future = CompletableFuture.allOf(
|
||||
new ModrinthVersionUploader().performUpload(release, false),
|
||||
new HangarVersionUploader().performUpload(release, false)
|
||||
);
|
||||
case "--dryrun" -> {
|
||||
LOGGER.info("Performing Dry-run for Modrinth and Hangar...");
|
||||
case "--modrinth" -> {
|
||||
modrinthRelease = new ModrinthRelease();
|
||||
future = new ModrinthVersionUploader().performUpload(release, modrinthRelease, dryrun);
|
||||
}
|
||||
case "--hangar" -> future = new HangarVersionUploader().performUpload(release, dryrun);
|
||||
case "--all" -> {
|
||||
modrinthRelease = new ModrinthRelease();
|
||||
future = CompletableFuture.allOf(
|
||||
new ModrinthVersionUploader().performUpload(release, true),
|
||||
new HangarVersionUploader().performUpload(release, true)
|
||||
new ModrinthVersionUploader().performUpload(release, modrinthRelease, dryrun),
|
||||
new HangarVersionUploader().performUpload(release, dryrun)
|
||||
);
|
||||
|
||||
try{
|
||||
future.join();
|
||||
}catch(Exception ex){
|
||||
LOGGER.warn("Exception while waiting for CompletableFutures to end...", ex);
|
||||
}
|
||||
|
||||
LOGGER.info("Dry-run completed!");
|
||||
return;
|
||||
}
|
||||
default -> {
|
||||
LOGGER.warn("Unknown argument '{}' provided. Supported are '--all', '--modrinth', '--hangar' and '--dryrun'", args[0]);
|
||||
LOGGER.warn("Unknown argument '{}' provided. Supported are '--all', '--modrinth' or '--hangar'", args[0]);
|
||||
System.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -99,11 +101,62 @@ public class VersionUploader{
|
||||
|
||||
try{
|
||||
future.join();
|
||||
LOGGER.info("Upload completed!");
|
||||
if(dryrun){
|
||||
LOGGER.info("Dryrun complete!");
|
||||
}else{
|
||||
LOGGER.info("Upload completed!");
|
||||
}
|
||||
}catch(Exception ex){
|
||||
LOGGER.warn("Upload was not successful! Encountered an Exception!", ex);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if(modrinthRelease == null || modrinthRelease.getReleases().isEmpty()){
|
||||
LOGGER.warn("No Modrinth release info on Discord to share... Skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
String webhookUrl = System.getenv("DISCORD_WEBHOOK_URL");
|
||||
if(webhookUrl == null || webhookUrl.isEmpty()){
|
||||
LOGGER.warn("No valid DISCORD_WEBHOOK_URL Environment Variable found. Skipping Webhook sending.");
|
||||
return;
|
||||
}
|
||||
|
||||
WebhookEmbedBuilder builder = new WebhookEmbedBuilder()
|
||||
.setTitle(new WebhookEmbed.EmbedTitle("New Release", null))
|
||||
.setDescription("A new release of AdvancedServerList is available on Modrinth for you to download!")
|
||||
.setColor(0x1BD96A);
|
||||
|
||||
for(Map.Entry<String, String> entry : modrinthRelease.getReleases().entrySet()){
|
||||
builder.addField(new WebhookEmbed.EmbedField(
|
||||
false,
|
||||
entry.getKey(),
|
||||
"https://modrinth.com/plugin/advancedserverlist/version/" + entry.getValue()
|
||||
));
|
||||
}
|
||||
|
||||
try(WebhookClient client = new WebhookClientBuilder(webhookUrl).build()){
|
||||
CompletableFuture<ReadonlyMessage> webhookFuture = client.send(builder.build()).whenComplete((readonlyMessage, throwable) -> {
|
||||
if(throwable != null){
|
||||
LOGGER.warn("Error while sending webhook message!", throwable);
|
||||
System.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.info("Webhook message send!");
|
||||
client.close();
|
||||
});
|
||||
|
||||
try{
|
||||
webhookFuture.join();
|
||||
}catch(Exception ex){
|
||||
LOGGER.warn("Unable to complete webhook message sending!", ex);
|
||||
System.exit(1);
|
||||
}
|
||||
}catch(Exception ex){
|
||||
LOGGER.warn("Encountered Exception while creating WebhookClient!", ex);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static String retrieveVersion(){
|
||||
|
||||
+8
-6
@@ -28,8 +28,10 @@ package ch.andre601.advancedserverlist.versionuploader.hangar;
|
||||
import ch.andre601.advancedserverlist.versionuploader.PlatformInfo;
|
||||
import ch.andre601.advancedserverlist.versionuploader.VersionUploader;
|
||||
import ch.andre601.advancedserverlist.versionuploader.data.CodebergRelease;
|
||||
import ch.andre601.advancedserverlist.versionuploader.hangar.version.*;
|
||||
|
||||
import ch.andre601.advancedserverlist.versionuploader.hangar.version.Dependency;
|
||||
import ch.andre601.advancedserverlist.versionuploader.hangar.version.MultipartObject;
|
||||
import ch.andre601.advancedserverlist.versionuploader.hangar.version.Platform;
|
||||
import ch.andre601.advancedserverlist.versionuploader.hangar.version.Version;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
@@ -90,9 +92,9 @@ public class HangarVersionUploader{
|
||||
boolean preRelease = release.prerelease();
|
||||
|
||||
final List<Path> filePaths = List.of(
|
||||
new File(PlatformInfo.PAPER.getFilePath().replace("{{version}}", pluginVersion)).toPath(),
|
||||
new File(PlatformInfo.BUNGEECORD.getFilePath().replace("{{version}}", pluginVersion)).toPath(),
|
||||
new File(PlatformInfo.VELOCITY.getFilePath().replace("{{version}}", pluginVersion)).toPath()
|
||||
new File(PlatformInfo.PAPER.getFilePaths().get(0).replace("{{version}}", pluginVersion)).toPath(),
|
||||
new File(PlatformInfo.BUNGEECORD.getFilePaths().get(0).replace("{{version}}", pluginVersion)).toPath(),
|
||||
new File(PlatformInfo.VELOCITY.getFilePaths().get(0).replace("{{version}}", pluginVersion)).toPath()
|
||||
);
|
||||
|
||||
final List<Dependency> paperDependencies = List.of(
|
||||
@@ -123,7 +125,7 @@ public class HangarVersionUploader{
|
||||
Platform.VELOCITY, velocityDependencies
|
||||
),
|
||||
Map.of(
|
||||
Platform.PAPER, List.of("1.19.x", "1.20.x"),
|
||||
Platform.PAPER, List.of("1.20.x"),
|
||||
Platform.WATERFALL, List.of("1.19.x", "1.20.x"),
|
||||
Platform.VELOCITY, Collections.singletonList("3.2")
|
||||
),
|
||||
|
||||
+35
-21
@@ -25,6 +25,7 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.versionuploader.modrinth;
|
||||
|
||||
import ch.andre601.advancedserverlist.versionuploader.ModrinthRelease;
|
||||
import ch.andre601.advancedserverlist.versionuploader.PlatformInfo;
|
||||
import ch.andre601.advancedserverlist.versionuploader.VersionUploader;
|
||||
import ch.andre601.advancedserverlist.versionuploader.data.CodebergRelease;
|
||||
@@ -38,8 +39,8 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class ModrinthVersionUploader{
|
||||
@@ -52,7 +53,6 @@ public class ModrinthVersionUploader{
|
||||
PlatformInfo.VELOCITY
|
||||
);
|
||||
private final List<String> versions = List.of(
|
||||
"1.19", "1.19.1", "1.19.2", "1.19.3", "1.19.4",
|
||||
"1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4"
|
||||
);
|
||||
|
||||
@@ -62,7 +62,7 @@ public class ModrinthVersionUploader{
|
||||
this.api = createClient();
|
||||
}
|
||||
|
||||
public CompletableFuture<?> performUpload(CodebergRelease release, boolean dryrun){
|
||||
public CompletableFuture<?> performUpload(CodebergRelease release, ModrinthRelease modrinthRelease, boolean dryrun){
|
||||
LOGGER.info("Starting ModrinthVersionUploader...");
|
||||
|
||||
if(api == null){
|
||||
@@ -82,37 +82,48 @@ public class ModrinthVersionUploader{
|
||||
final boolean prerelease = release.prerelease();
|
||||
|
||||
CompletableFuture<?>[] futures = new CompletableFuture[platforms.size()];
|
||||
|
||||
List<ProjectVersion.ProjectDependency> paperDependencies = List.of(
|
||||
new ProjectVersion.ProjectDependency(null, "VCAqN1ln", null, ProjectVersion.ProjectDependencyType.OPTIONAL), // Maintenance
|
||||
new ProjectVersion.ProjectDependency(null, "P1OZGk5p", null, ProjectVersion.ProjectDependencyType.OPTIONAL) // ViaVersion
|
||||
);
|
||||
List<ProjectVersion.ProjectDependency> bungeeDependencies = List.of(
|
||||
new ProjectVersion.ProjectDependency(null, "VCAqN1ln", null, ProjectVersion.ProjectDependencyType.OPTIONAL), // Maintenance
|
||||
new ProjectVersion.ProjectDependency(null, "bEIUEGTX", null, ProjectVersion.ProjectDependencyType.OPTIONAL) // PAPIProxyBridge
|
||||
);
|
||||
List<ProjectVersion.ProjectDependency> velocityDependencies = List.of(
|
||||
new ProjectVersion.ProjectDependency(null, "VCAqN1ln", null, ProjectVersion.ProjectDependencyType.OPTIONAL), // Maintenance
|
||||
new ProjectVersion.ProjectDependency(null, "bEIUEGTX", null, ProjectVersion.ProjectDependencyType.OPTIONAL) // PAPIProxyBridge
|
||||
);
|
||||
|
||||
for(int i = 0; i < platforms.size(); i++){
|
||||
LOGGER.info("Creating release for platform {}...", platforms.get(i).getPlatform());
|
||||
|
||||
File file = new File(platforms.get(i).getFilePath().replace("{{version}}", pluginVersion));
|
||||
List<File> files = platforms.get(i).getFilePaths().stream()
|
||||
.map(path -> new File(path.replace("{{version}}", pluginVersion)))
|
||||
.filter(File::exists)
|
||||
.toList();
|
||||
|
||||
List<ProjectVersion.ProjectDependency> dependencies = new ArrayList<>();
|
||||
// Maintenance plugin
|
||||
dependencies.add(new ProjectVersion.ProjectDependency(null, "VCAqN1ln", null, ProjectVersion.ProjectDependencyType.OPTIONAL));
|
||||
// ViaVersion plugin
|
||||
dependencies.add(new ProjectVersion.ProjectDependency(null, "P1OZGk5p", null, ProjectVersion.ProjectDependencyType.OPTIONAL));
|
||||
if(!platforms.get(i).getPlatform().equalsIgnoreCase("paper")){
|
||||
// PAPIProxyBridge plugin
|
||||
dependencies.add(new ProjectVersion.ProjectDependency(null, "bEIUEGTX", null, ProjectVersion.ProjectDependencyType.OPTIONAL));
|
||||
}
|
||||
|
||||
CreateVersion.CreateVersionRequest request = CreateVersion.CreateVersionRequest.builder()
|
||||
CreateVersion.CreateVersionRequest.CreateVersionRequestBuilder builder = CreateVersion.CreateVersionRequest.builder()
|
||||
.projectId("xss83sOY")
|
||||
.name(String.format("v%s (%s)", releaseVersion, String.join(", ", platforms.get(i).getLoaders())))
|
||||
.versionNumber(releaseVersion)
|
||||
.changelog(changelog.replaceAll("\r\n", "\n"))
|
||||
.featured(false)
|
||||
.files(file)
|
||||
.files(files)
|
||||
.gameVersions(versions)
|
||||
.loaders(platforms.get(i).getLoaders())
|
||||
.versionType(prerelease ? ProjectVersion.VersionType.BETA : ProjectVersion.VersionType.RELEASE)
|
||||
.dependencies(dependencies)
|
||||
.build();
|
||||
.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);
|
||||
}
|
||||
|
||||
if(dryrun){
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
String json = gson.toJson(request);
|
||||
String json = gson.toJson(builder.build());
|
||||
|
||||
LOGGER.info("JSON Data to send: {}", json);
|
||||
|
||||
@@ -120,7 +131,8 @@ public class ModrinthVersionUploader{
|
||||
continue;
|
||||
}
|
||||
|
||||
futures[i] = api.versions().createProjectVersion(request).whenComplete(((projectVersion, throwable) -> {
|
||||
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);
|
||||
return;
|
||||
@@ -128,6 +140,8 @@ public class ModrinthVersionUploader{
|
||||
|
||||
LOGGER.info("Created new release!");
|
||||
LOGGER.info("Link: https://modrinth.com/plugin/advancedserverlist/version/{}", projectVersion.getId());
|
||||
|
||||
modrinthRelease.addRelease(String.join(", ", platforms.get(index).getLoaders()), projectVersion.getId());
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user