Compare commits

...
11 Commits
Author SHA1 Message Date
Andre_601 0d84335db9 Merge pull request #9 from Andre601/feature/favicon-support
Add Favicon support for Server list profiles.
2022-08-21 23:32:46 +02:00
Andre601 50f878e39c Add assets 2022-08-21 23:30:59 +02:00
Andre601 b88ee87c96 Add notes to favicon setting 2022-08-21 23:28:11 +02:00
Andre601 a5f6e689f0 Shade in Caffeine 2022-08-21 01:31:20 +02:00
Andre601 dd0bc8a43a Cache the bytes array 2022-08-20 23:53:32 +02:00
Andre601 563362504f Use some kind of caching... I guess? 2022-08-20 23:43:55 +02:00
Andre601 bd95be080e Add missing profile comments 2022-08-18 16:11:04 +02:00
Andre601 2d02d48d3c Add Favicon support for Server list profiles. 2022-08-18 16:05:00 +02:00
Andre_601 15f7b5def3 Update README.md 2022-08-18 00:02:49 +02:00
Andre_601 f37813d5b7 Merge pull request #8 from Andre601/feature/xMore-option
Add xMore profile option
2022-08-17 21:26:17 +02:00
Andre601 93c2dda56b Add xMore profile option 2022-08-17 21:19:38 +02:00
15 changed files with 355 additions and 46 deletions

No files matched your search

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

+11 -9
View File
@@ -4,30 +4,30 @@
AdvancedServerList is a plugin made for SpigotMC, PaperMC, BungeeCord/Waterfall and Velocity. It allows you to create server list profiles to display based on priority and conditions.
## What is a Server List Profile?
A Server List Profile is a YAML file located in the plugin’s profiles folder having a priority, conditions (Optional), MOTD, Player count text, hover for player count and hiding the player count completely (Changing it to ???)
A Server List Profile is a YAML file located in the plugin’s profiles folder having a priority, conditions (Optional), MOTD, Player count text, hover for player count and hiding the player count completely (Changing it to `???`)
> [*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 highest priority (Higher number = higher priority) be selected. Having no conditions makes the profile automatically return true.
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.
> [Read More][conditions]
> [*Read More*][conditions]
### Placeholders
Placeholders can be used within conditions to further customize them. They can also be used in any other text option (motd, playerCount and players) to display their respective value.
The format is ${<target> <identifier>} which was adopted from BungeeTabListPlus. Depending on what platform you use the plugin on are only specific placeholders available.
Placeholders can be used within conditions to further customize them. They can also be used in any other text option (motd, playerCount and players) 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 can you also use placeholders from PlaceholderAPI using its %<identifier>_<values>% format. PlaceholderAPI needs to be installed for that.
When using the SpigotMC/PaperMC version can you also use placeholders from [PlaceholderAPI][placeholderapi] using its `%<identifier>_<values>%` placeholder format. PlaceholderAPI needs to be installed for that.
> [Read More][placeholders]
> [*Read More*][placeholders]
### Formatting
The plugin uses the MiniMessage format for a consistent, easy way of formatting your text.
Depending on the option you use can you use more advanced formatting options such as HEX colours and gradients (Only available for the motd option).
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.
> [Read More][minimessage]
> [*Read More*][minimessage]
## Downloads
AdvancedServerList can be downloaded from the following places:
@@ -47,6 +47,8 @@ Here are screenshots showing the plugin in action. Do you have your own screensh
[placeholders]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#placeholders
[minimessage]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#minimessage
[placeholderapi]: https://www.spigotmc.org/resources/6245/
[modrinth]: https://modrinth.com/mod/advancedserverlist
[spigot]: https://www.spigotmc.org/resources/102910/
[hangar]: https://hangar.benndorf.dev/Andre_601/AdvancedServerList
@@ -31,9 +31,12 @@ import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.ProfileManager;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
import net.md_5.bungee.api.Favicon;
import net.md_5.bungee.api.ServerPing;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.event.ProxyPingEvent;
@@ -41,6 +44,7 @@ import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler;
import net.md_5.bungee.event.EventPriority;
import java.awt.image.BufferedImage;
import java.net.InetSocketAddress;
public class PingEvent implements Listener{
@@ -59,15 +63,15 @@ public class PingEvent implements Listener{
if(protocol == null)
return;
InetSocketAddress address = (InetSocketAddress)event.getConnection().getSocketAddress();
String playerName = plugin.getCore().getPlayerHandler().getPlayerByIp(
((InetSocketAddress)event.getConnection().getSocketAddress()).getHostString()
);
InetSocketAddress host = event.getConnection().getVirtualHost();
int online = ping.getPlayers().getOnline();
int max = ping.getPlayers().getMax();
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(
new BungeePlayer(plugin.getCore().getPlayerHandler().getPlayerByIp(address.getHostString()), protocol.getProtocol())
);
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(new BungeePlayer(playerName, protocol.getProtocol()));
ServerPlaceholders serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
ServerListProfile profile = ProfileManager.get(plugin.getCore())
@@ -78,8 +82,8 @@ public class PingEvent implements Listener{
if(profile == null)
return;
if(profile.isOneMore()){
max = online + 1;
if(profile.getXMore() >= 0){
max = online + profile.getXMore();
ping.getPlayers().setMax(max);
}
@@ -126,10 +130,26 @@ public class PingEvent implements Listener{
if(playerInfos.length > 0)
ping.getPlayers().setSample(playerInfos);
}
ping.setFavicon(ping.getFaviconObject());
if(!profile.getFavicon().isEmpty()){
String favName = StringReplacer.replace(profile.getFavicon(), playerPlaceholders.getReplacements());
BufferedImage img = new FaviconHandler(plugin.getCore(), favName).get().getAsBufferedImage();
if(img == null){
plugin.getPluginLogger().warn("Could not obtain valid Favicon to use.");
ping.setFavicon(ping.getFaviconObject());
}else{
try{
Favicon favicon = Favicon.create(img);
ping.setFavicon(favicon);
}catch(Exception ex){
plugin.getPluginLogger().warn("Unable to override Favicon. Reason: %s", ex.getMessage());
ping.setFavicon(ping.getFaviconObject());
}
}
}
ping.setVersion(protocol);
event.setResponse(ping);
+12
View File
@@ -64,6 +64,12 @@
<artifactId>adventure-text-serializer-legacy</artifactId>
<version>4.11.0</version>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>1.3.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
@@ -86,6 +92,12 @@
<version>3.3.0</version>
<configuration>
<minimizeJar>true</minimizeJar>
<relocations>
<relocation>
<pattern>com.github.benmanes</pattern>
<shadedPattern>ch.andre601.advancedserverlist.core.depends.caffeine</shadedPattern>
</relocation>
</relocations>
<filters>
<filter>
<artifact>*:*</artifact>
@@ -29,9 +29,7 @@ import ch.andre601.advancedserverlist.core.commands.CommandHandler;
import ch.andre601.advancedserverlist.core.file.FileHandler;
import ch.andre601.advancedserverlist.core.interfaces.PluginCore;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.PlayerHandler;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import java.io.IOException;
import java.io.InputStream;
@@ -113,7 +111,7 @@ public class AdvancedServerList{
getPluginLogger().info("Starting AdvancedServerList v%s...", version);
getPluginLogger().info("Proxy: " + plugin.getPlatformName() + " " + plugin.getPlatformVersion());
getPluginLogger().info("Platform: " + plugin.getPlatformName() + " " + plugin.getPlatformVersion());
if(getFileHandler().loadConfig()){
getPluginLogger().info("Successfully loaded config.yml!");
@@ -129,6 +127,9 @@ public class AdvancedServerList{
return;
}
if(!getPath().resolve("favicons").toFile().exists() && getPath().resolve("favicons").toFile().mkdirs())
getPluginLogger().info("Successfully created favicons folder.");
getPluginLogger().info("Loading Commands...");
plugin.loadCommands();
getPluginLogger().info("Commands loaded!");
@@ -43,8 +43,9 @@ public class ServerListProfile{
private final List<String> motd;
private final List<String> players;
private final String playerCount;
private final String favicon;
private final boolean hidePlayers;
private final boolean oneMore;
private final int xMore;
public ServerListProfile(ConfigurationNode node, PluginLogger logger){
this.priority = node.node("priority").getInt();
@@ -53,8 +54,9 @@ public class ServerListProfile{
this.motd = getList(node, "motd", true);
this.players = getList(node, "players", false);
this.playerCount = node.node("playerCount").getString("");
this.favicon = node.node("favicon").getString("");
this.hidePlayers = node.node("hidePlayers").getBoolean();
this.oneMore = node.node("oneMore").getBoolean();
this.xMore = node.node("xMore").getInt(-1);
}
public int getPriority(){
@@ -73,12 +75,16 @@ public class ServerListProfile{
return playerCount;
}
public String getFavicon(){
return favicon;
}
public boolean shouldHidePlayers(){
return hidePlayers;
}
public boolean isOneMore(){
return oneMore;
public int getXMore(){
return xMore;
}
public boolean evalConditions(Map<String, Object> replacements){
@@ -0,0 +1,51 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.favicon;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;
public class FaviconHandler{
private final Cache<String, GenericFavicon> favicons = Caffeine.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.build();
private final AdvancedServerList core;
private final String input;
public FaviconHandler(AdvancedServerList core, String input){
this.core = core;
this.input = input;
}
public GenericFavicon get(){
return favicons.get(input, k -> new GenericFavicon(core, input));
}
}
@@ -0,0 +1,141 @@
/*
* MIT License
*
* Copyright (c) 2022 Andre_601
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
package ch.andre601.advancedserverlist.core.profiles.favicon;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.Locale;
public class GenericFavicon{
private final AdvancedServerList core;
private final String input;
private final BufferedImage image;
private byte[] bytes = null;
public GenericFavicon(AdvancedServerList core, String input){
this.core = core;
this.input = input;
this.image = resolve();
}
public byte[] getAsByteArray(){
if(bytes != null && bytes.length > 0)
return bytes;
if(image == null){
this.core.getPluginLogger().warn("Cannot convert Favicon BufferedImage to Byte array. BufferedImage was null.");
return null;
}
try{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.setUseCache(false);
ImageIO.write(image, "PNG", baos);
return (bytes = baos.toByteArray());
}catch(IOException ex){
this.core.getPluginLogger().warn("Cannot convert Favicon BufferedImage to Byte array. %s", ex.getMessage());
return null;
}
}
public BufferedImage getAsBufferedImage(){
return image;
}
private BufferedImage resolve(){
InputStream stream;
if(input.toLowerCase(Locale.ROOT).startsWith("https://")){
stream = getFromUrl(input);
}else
if(input.toLowerCase(Locale.ROOT).endsWith(".png")){
File folder = core.getPath().resolve("favicons").toFile();
if(!folder.exists()){
this.core.getPluginLogger().warn("Cannot get Favicon for profile. Favicons folder is not present.");
return null;
}
File file = new File(folder, input);
try{
stream = new FileInputStream(file);
}catch(FileNotFoundException ex){
this.core.getPluginLogger().warn("Unable to create Favicon data. %s", ex.getMessage());
return null;
}
}else{
stream = getFromUrl("https://mc-heads.net/avatar/" + input + "/64");
}
if(stream == null){
this.core.getPluginLogger().warn("Unable to get Data for Favicon. InputStream was null.");
return null;
}
try{
BufferedImage original = ImageIO.read(stream);
if(original == null)
return null;
BufferedImage favicon = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
Graphics2D img = favicon.createGraphics();
// We use this to resize the image to 64x64 pixels.
img.drawImage(original, 0, 0, 64, 64, null);
img.dispose();
return favicon;
}catch(IOException ex){
this.core.getPluginLogger().warn("Cannot resize favicon into 64x64. %s", ex.getMessage());
return null;
}
}
private InputStream getFromUrl(String url){
try{
URL avatarUrl = new URL(url);
URLConnection connection = avatarUrl.openConnection();
connection.setRequestProperty("User-Agent", "AdvancedServerList/" + core.getVersion());
connection.connect();
return connection.getInputStream();
}catch(IOException ex){
this.core.getPluginLogger().warn("Unable to connect to URL %s! %s", url, ex.getMessage());
return null;
}
}
}
+24 -5
View File
@@ -60,11 +60,30 @@ players:
playerCount: '<grey>Text'
#
# When set to true, will the ${server maxPlayers} placeholder display the online players + 1
# This means that if 20 players are online, 21 would be displayed by the placeholder with this option enabled.
# Allows you to override the default Favicon used by the Server/Proxy.
# You can provide three specific inputs:
# - A valid URL pointing to a PNG file.
# - ${player name} for a per-player avatar being displayed (Uses mc-heads.net)
# - Image file name (i.e. example.png) for a file in the "favicons" folder.
#
# Note that the placeholder will not be affected in the conditions.
# NOTE:
# - The favicon will be cached for 5 minutes to avoid spam and rate limits.
# - BungeeCord/Waterfall may report issues that the plugin takes a long time to process.
# This is something I cannot really get improved without help.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profile#onemore
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#favicon
#
oneMore: false
favicon: ''
#
# When set to 0 or higher will alter the max player count to the online count + xMore.
# Example: With 20 online players would 'xMore: 1' show 20/21 and 'xMore: 0' show 20/20
#
# Note that this will also manipulate the ${server playersMax} placeholder when used
# in motd, players or playerCount.
#
# Remove this option or set it to -1 to not alter the max player count.
#
# Read more: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#xmore
#
xMore: -1
@@ -28,6 +28,8 @@ package ch.andre601.advancedserverlist.paper.events;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.ProfileManager;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
@@ -40,7 +42,9 @@ import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.util.CachedServerIcon;
import java.awt.image.BufferedImage;
import java.net.InetSocketAddress;
import java.util.*;
@@ -74,8 +78,8 @@ public class PingEvent implements Listener{
if(profile == null)
return;
if(profile.isOneMore()){
max = online + 1;
if(profile.getXMore() >= 0){
max = online + profile.getXMore();
event.setMaxPlayers(max);
}
@@ -119,7 +123,23 @@ public class PingEvent implements Listener{
event.getPlayerSample().addAll(getPlayers(profile.getPlayers(), playerPlaceholders, serverPlaceholders, player.getPlayer()));
}
event.setServerIcon(event.getServerIcon());
if(!profile.getFavicon().isEmpty()){
String favName = StringReplacer.replace(profile.getFavicon(), playerPlaceholders.getReplacements());
BufferedImage img = new FaviconHandler(plugin.getCore(), favName).get().getAsBufferedImage();
if(img == null){
plugin.getPluginLogger().warn("Could not obtain valid Favicon to use.");
event.setServerIcon(event.getServerIcon());
}else{
try{
CachedServerIcon favicon = Bukkit.loadServerIcon(img);
event.setServerIcon(favicon);
}catch(Exception ex){
plugin.getPluginLogger().warn("Unable to override Favicon. Reason: %s", ex.getMessage());
event.setServerIcon(event.getServerIcon());
}
}
}
}
private List<PlayerProfile> getPlayers(List<String> lines, Placeholders playerPlaceholders, Placeholders serverPlaceholders, OfflinePlayer player){
+1 -1
View File
@@ -12,7 +12,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<plugin.version>1.3.0</plugin.version>
<plugin.version>1.5.0</plugin.version>
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
<maven.compiler.source>16</maven.compiler.source>
@@ -28,6 +28,8 @@ package ch.andre601.advancedserverlist.spigot.events;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.ProfileManager;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
@@ -101,8 +103,8 @@ public class PingEvent implements Listener{
if(profile == null)
return;
if(profile.isOneMore()){
max = online + 1;
if(profile.getXMore() >= 0){
max = online + profile.getXMore();
ping.setPlayersMaximum(max);
}
@@ -156,6 +158,24 @@ public class PingEvent implements Listener{
.toString()
));
}
if(!profile.getFavicon().isEmpty()){
String favName = StringReplacer.replace(profile.getFavicon(), playerPlaceholders.getReplacements());
byte[] bytes = new FaviconHandler(spigotPlugin.getCore(), favName).get().getAsByteArray();
if(bytes == null){
spigotPlugin.getPluginLogger().warn("Could not obtain valid Favicon to use.");
ping.setFavicon(ping.getFavicon());
}else{
try{
WrappedServerPing.CompressedImage favicon = WrappedServerPing.CompressedImage.fromPng(bytes);
ping.setFavicon(favicon);
}catch(Exception ex){
spigotPlugin.getPluginLogger().warn("Unable to override Favicon. Reason: %s", ex.getMessage());
ping.setFavicon(ping.getFavicon());
}
}
}
}
});
}
+5 -5
View File
@@ -8,11 +8,11 @@ main: 'ch.andre601.advancedserverlist.spigot.SpigotCore'
api-version: 1.19
libraries:
- 'org.spongepowered:configurate-yaml:${plugin.depend.configurate}'
- 'net.kyori:adventure-api:${plugin.depend.kyori-adventure}'
- 'net.kyori:adventure-text-minimessage:${plugin.depend.kyori-minimessage}'
- 'net.kyori:adventure-text-serializer-legacy:${plugin.depend.kyori-legacy}'
- 'net.kyori:adventure-platform-bukkit:${plugin.depend.kyori-platform-bukkit}'
- 'org.spongepowered:configurate-yaml:4.1.2'
- 'net.kyori:adventure-api:4.11.0'
- 'net.kyori:adventure-text-minimessage:4.11.0'
- 'net.kyori:adventure-text-serializer-legacy:4.11.0'
- 'net.kyori:adventure-platform-bukkit:4.1.2'
softdepend:
- 'ProtocolLib'
@@ -29,6 +29,8 @@ import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.ProfileManager;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
import ch.andre601.advancedserverlist.velocity.VelocityCore;
@@ -37,7 +39,9 @@ import com.velocitypowered.api.event.PostOrder;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
import com.velocitypowered.api.proxy.server.ServerPing;
import com.velocitypowered.api.util.Favicon;
import java.awt.image.BufferedImage;
import java.net.InetSocketAddress;
import java.util.List;
@@ -58,15 +62,13 @@ public class PingEvent{
return;
ServerPing.Builder builder = ping.asBuilder();
InetSocketAddress address = event.getConnection().getRemoteAddress();
String playerName = plugin.getCore().getPlayerHandler().getPlayerByIp(event.getConnection().getRemoteAddress().getHostString());
InetSocketAddress host = event.getConnection().getVirtualHost().orElse(null);
int online = builder.getOnlinePlayers();
int max = builder.getMaximumPlayers();
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(
new VelocityPlayer(plugin.getCore().getPlayerHandler().getPlayerByIp(address.getHostString()), protocol.getProtocol())
);
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(new VelocityPlayer(playerName, protocol.getProtocol()));
ServerPlaceholders serverPlaceholders = new ServerPlaceholders(online, max, host == null ? null : host.getHostString());
ServerListProfile profile = ProfileManager.get(plugin.getCore())
@@ -77,8 +79,8 @@ public class PingEvent{
if(profile == null)
return;
if(profile.isOneMore()){
max = online + 1;
if(profile.getXMore() >= 0){
max = online + profile.getXMore();
builder.maximumPlayers(max);
}
@@ -123,6 +125,21 @@ public class PingEvent{
builder.clearSamplePlayers().samplePlayers(playerSamples);
}
if(!profile.getFavicon().isEmpty()){
String favName = StringReplacer.replace(profile.getFavicon(), playerPlaceholders.getReplacements());
BufferedImage img = new FaviconHandler(plugin.getCore(), favName).get().getAsBufferedImage();
if(img == null){
plugin.getPluginLogger().warn("Could not obtain valid Favicon to use.");
}else{
try{
Favicon favicon = Favicon.create(img);
builder.favicon(favicon);
}catch(Exception ex){
plugin.getPluginLogger().warn("Unable to override Favicon. Reason: %s", ex.getMessage());}
}
}
event.setPing(builder.build());
}
}