From 57c2523a88a1c36fa0978fff38116ac19e8f3bd0 Mon Sep 17 00:00:00 2001 From: Leo Date: Thu, 7 May 2026 13:54:18 +0200 Subject: [PATCH] feat: read images from data dir and map to hostname in filename --- .../customServerIcon/CustomServerIcon.java | 68 +++++++++++++++---- .../customServerIcon/PluginListener.java | 38 +++++++++++ 2 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/leohabrom/velocity/customServerIcon/PluginListener.java diff --git a/src/main/java/com/leohabrom/velocity/customServerIcon/CustomServerIcon.java b/src/main/java/com/leohabrom/velocity/customServerIcon/CustomServerIcon.java index f2cd292..b493d43 100644 --- a/src/main/java/com/leohabrom/velocity/customServerIcon/CustomServerIcon.java +++ b/src/main/java/com/leohabrom/velocity/customServerIcon/CustomServerIcon.java @@ -3,31 +3,75 @@ package com.leohabrom.velocity.customServerIcon; import com.google.inject.Inject; import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; import com.velocitypowered.api.event.Subscribe; -import com.velocitypowered.api.event.proxy.ProxyPingEvent; import com.velocitypowered.api.plugin.Plugin; +import com.velocitypowered.api.plugin.annotation.DataDirectory; +import com.velocitypowered.api.proxy.ProxyServer; import org.slf4j.Logger; -import java.net.InetSocketAddress; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.concurrent.ConcurrentHashMap; @Plugin(id = "custom-server-icon", name = "Custom Server Icon", version = "1.0-SNAPSHOT", - url = "https://", description = "I did it!", authors = {"Me"}) + url = "https://git.leohabrom.com/Jinx/velocity-custom-server-icon", description = "Velocity Plugin to set custom icons for different hostnames", authors = {"Leo Habrom"}) public class CustomServerIcon { + private final ProxyServer server; + private final Logger logger; + private final Path dataDirectory; + private final ConcurrentHashMap customIcons = new ConcurrentHashMap<>(); + @Inject - private Logger logger; + public CustomServerIcon(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) { + this.server = server; + this.logger = logger; + this.dataDirectory = dataDirectory; + + logger.info("Hello from Custom Server Icon"); + } @Subscribe public void onProxyInitialization(ProxyInitializeEvent event) { - System.out.println("Hello from Custom Server Icon"); - // Plugin initialization logic goes here - } + try { + File dataDir = dataDirectory.toFile(); + if ((!dataDir.exists() && !dataDir.mkdirs()) || !dataDir.isDirectory()) { + logger.warn("couldn't create data directory, disabling plugin!"); + return; + } + File[] files = dataDir.listFiles((dir, name) -> name.endsWith(".png")); + if (files == null) { + logger.warn("couldn't read files in the data directory, disabling plugin!"); + return; + } + logger.info("Found {} images in the data directory",files.length); + for (File file : files) { + String hostname = file.getName().substring(0,file.getName().length()-4); + try { + BufferedImage image = ImageIO.read(file); + if (image != null) { + if (image.getWidth() != 64 || image.getHeight() != 64) { + logger.warn("image {} is not 64x64 pixels, skipping",file.getName()); + continue; + } + customIcons.put(hostname,image); + logger.info("added custom icon for {}",hostname); + } + } catch (IOException e) { + logger.warn("couldn't read image {}", file.getName()); + } + } - @Subscribe - public void onProxyPing(ProxyPingEvent event) { - InetSocketAddress address = event.getConnection().getVirtualHost().orElse(null); - if (address != null) { - System.out.println(address.getHostName()); + } catch (SecurityException securityException) { + logger.warn("no read access in the data directory, disabling plugin!"); + return; } + + + server.getEventManager().register(this, new PluginListener(logger,customIcons)); + logger.info("Registered Plugin"); } } diff --git a/src/main/java/com/leohabrom/velocity/customServerIcon/PluginListener.java b/src/main/java/com/leohabrom/velocity/customServerIcon/PluginListener.java new file mode 100644 index 0000000..51b1f31 --- /dev/null +++ b/src/main/java/com/leohabrom/velocity/customServerIcon/PluginListener.java @@ -0,0 +1,38 @@ +package com.leohabrom.velocity.customServerIcon; + +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.proxy.ProxyPingEvent; +import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.api.util.Favicon; +import org.slf4j.Logger; + +import java.awt.image.BufferedImage; +import java.net.InetSocketAddress; +import java.util.concurrent.ConcurrentHashMap; + +public class PluginListener { + + private final Logger logger; + private final ConcurrentHashMap customIcons; + + + public PluginListener(Logger logger, ConcurrentHashMap customIcons) { + this.logger = logger; + this.customIcons = customIcons; + } + + @Subscribe + public void onProxyPing(ProxyPingEvent event) { + InetSocketAddress address = event.getConnection().getVirtualHost().orElse(null); + if (address != null) { + logger.info("Received ping to: {} from: {}", address.getHostName(), event.getConnection().getRemoteAddress().getAddress()); + String host = address.getHostName(); + customIcons.forEach((customHost,image)-> { + if (customHost.equalsIgnoreCase(host) && image != null && image.getHeight() == 64 && image.getWidth() == 64) { + logger.info("Set custom image for host: {}",host); + event.setPing(event.getPing().asBuilder().favicon(Favicon.create(image)).build()); + } + }); + } + } +}