diff --git a/pom.xml b/pom.xml index 097a44f..98a34bf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,15 +4,15 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - me.itsnathang - PictureLogin - 1.6 + me.nickv + PictureLogin-Continued + 1.0.6 jar Picture Login - NathanG + NathanG, _NickV me.itsnathang.picturelogin.PictureLogin @@ -23,7 +23,7 @@ placeholderapi - http://repo.extendedclip.com/content/repositories/placeholderapi/ + https://repo.extendedclip.com/content/repositories/placeholderapi/ CodeMC @@ -33,6 +33,10 @@ minedown-repo https://repo.minebench.de/ + + sonatype-oss-snapshots1 + https://s01.oss.sonatype.org/content/repositories/snapshots/ + @@ -45,7 +49,7 @@ org.bstats bstats-bukkit - 1.7 + 3.0.0 compile @@ -66,10 +70,16 @@ 1.6.1-SNAPSHOT compile + + net.kyori + adventure-text-minimessage + 4.10.1 + - src/main/java + ${dir} + clean install @@ -79,11 +89,12 @@ + org.apache.maven.plugins maven-compiler-plugin 3.1 - 1.8 - 1.8 + 16 + 16 @@ -94,7 +105,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.1.0 + 3.3.0 @@ -130,5 +141,5 @@ - + \ No newline at end of file diff --git a/readme.md b/readme.md index da0e643..83b98df 100644 --- a/readme.md +++ b/readme.md @@ -1,16 +1,27 @@ -Picture Login ![GitHub release (latest by date)](https://img.shields.io/github/v/release/ItsNathanG/PictureLogin?style=flat-square) +PictureLogin-Continued [![Version](https://img.shields.io/badge/version-1.0.4-blue)](https://www.spigotmc.org/resources/picturelogin-continued.101216/) === -Picture Login provides a much nicer login message by displaying a picture of the player's head inside of chat. +This is a popular plugin for Minecraft servers (over 50,000 downloads) that has sadly been unsupported for a while; I've updated it to Minecraft 1.18 and will be supporting future versions! (Now confirmed working on Minecraft 1.21.1) -
- +PictureLogin creates a fancy login message by displaying a picture of the player's head inside of chat. - -
+![demo](https://user-images.githubusercontent.com/60233722/163606833-27671a07-1187-424f-abf7-f5a5d35abda8.PNG) -It is a plugin for [Spigot](http://www.spigotmc.org/) and you can find further information [here, on it's plugin page](http://www.spigotmc.org/resources/picture-login.4514/). +Obtaining the plugin +--- +You can download the plugin over on Spigot: https://www.spigotmc.org/resources/picturelogin-continued.101216/ + +Credit to... +--- + +- The original plugin author, ItsNathanG +- bobacadodl for his Image Message Library +- Crafatar for their avatar service + +Support [![Discord](https://img.shields.io/badge/discord-Nick's%20Place-orange)](https://discord.gg/fGzb73sPmV) +--- +You can reach out to me on the Spigot forums or here on GitHub, although the best way to reach me is on Discord. -License +License [![License](https://img.shields.io/github/license/Nicholas-Vo/PictureLogin-Continued)](https://github.com/Nicholas-Vo/PictureLogin-Continued/blob/master/LICENSE) --- -This plugin is licensed under the MIT License. For more information please refer to LICENSE. \ No newline at end of file +This plugin is licensed under the MIT License. For more information please refer to LICENSE. diff --git a/src/main/java/com/bobacadodl/imgmessage/ImageChar.java b/src/main/java/com/bobacadodl/imgmessage/ImageChar.java index 86bb74c..c431363 100644 --- a/src/main/java/com/bobacadodl/imgmessage/ImageChar.java +++ b/src/main/java/com/bobacadodl/imgmessage/ImageChar.java @@ -10,7 +10,7 @@ public enum ImageChar { DARK_SHADE('\u2593'), MEDIUM_SHADE('\u2592'), LIGHT_SHADE('\u2591'); - private char c; + private final char c; ImageChar(char c) { this.c = c; diff --git a/src/main/java/com/bobacadodl/imgmessage/ImageMessage.java b/src/main/java/com/bobacadodl/imgmessage/ImageMessage.java index 22a41f4..2389e2a 100644 --- a/src/main/java/com/bobacadodl/imgmessage/ImageMessage.java +++ b/src/main/java/com/bobacadodl/imgmessage/ImageMessage.java @@ -1,10 +1,10 @@ package com.bobacadodl.imgmessage; -import org.bukkit.ChatColor; +import net.md_5.bungee.api.ChatColor; import org.bukkit.entity.Player; import org.bukkit.util.ChatPaginator; -import java.awt.*; +import java.awt.Color; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; @@ -17,25 +17,6 @@ public class ImageMessage { private final static char TRANSPARENT_CHAR = ' '; - private final Color[] colors = { - new Color(0, 0, 0), - new Color(0, 0, 170), - new Color(0, 170, 0), - new Color(0, 170, 170), - new Color(170, 0, 0), - new Color(170, 0, 170), - new Color(255, 170, 0), - new Color(170, 170, 170), - new Color(85, 85, 85), - new Color(85, 85, 255), - new Color(85, 255, 85), - new Color(85, 255, 255), - new Color(255, 85, 85), - new Color(255, 85, 255), - new Color(255, 255, 85), - new Color(255, 255, 255), - }; - private String[] lines; public ImageMessage(BufferedImage image, int height, char imgChar) { @@ -92,12 +73,12 @@ private ChatColor[][] toChatColorArray(BufferedImage image, int height) { private String[] toImgMessage(ChatColor[][] colors, char imgchar) { lines = new String[colors[0].length]; for (int y = 0; y < colors[0].length; y++) { - String line = ""; - for (int x = 0; x < colors.length; x++) { - ChatColor color = colors[x][y]; - line += (color != null) ? colors[x][y].toString() + imgchar : TRANSPARENT_CHAR; + StringBuilder line = new StringBuilder(); + for (ChatColor[] chatColors : colors) { + ChatColor color = chatColors[y]; + line.append((color != null) ? chatColors[y].toString() + imgchar : TRANSPARENT_CHAR); } - lines[y] = line + ChatColor.RESET; + lines[y] = line.toString() + ChatColor.RESET; } return lines; } @@ -127,31 +108,11 @@ private boolean areIdentical(Color c1, Color c2) { return Math.abs(c1.getRed() - c2.getRed()) <= 5 && Math.abs(c1.getGreen() - c2.getGreen()) <= 5 && Math.abs(c1.getBlue() - c2.getBlue()) <= 5; - } private ChatColor getClosestChatColor(Color color) { if (color.getAlpha() < 128) return null; - - int index = 0; - double best = -1; - - for (int i = 0; i < colors.length; i++) { - if (areIdentical(colors[i], color)) { - return ChatColor.values()[i]; - } - } - - for (int i = 0; i < colors.length; i++) { - double distance = getDistance(color, colors[i]); - if (distance < best || best == -1) { - best = distance; - index = i; - } - } - - // Minecraft has 15 colors - return ChatColor.values()[index]; + return ChatColor.of(color); } private String center(String s, int length) { @@ -161,11 +122,7 @@ private String center(String s, int length) { return s; } else { int leftPadding = (length - s.length()) / 2; - StringBuilder leftBuilder = new StringBuilder(); - for (int i = 0; i < leftPadding; i++) { - leftBuilder.append(" "); - } - return leftBuilder.toString() + s; + return " ".repeat(leftPadding) + s; } } diff --git a/src/main/java/me/itsnathang/picturelogin/PictureLogin.java b/src/main/java/me/itsnathang/picturelogin/PictureLogin.java index f9b3f31..31061de 100644 --- a/src/main/java/me/itsnathang/picturelogin/PictureLogin.java +++ b/src/main/java/me/itsnathang/picturelogin/PictureLogin.java @@ -1,56 +1,60 @@ package me.itsnathang.picturelogin; -import me.itsnathang.picturelogin.listeners.JoinListener; -import me.itsnathang.picturelogin.listeners.QuitListener; import me.itsnathang.picturelogin.commands.BaseCommand; import me.itsnathang.picturelogin.config.ConfigManager; +import me.itsnathang.picturelogin.listeners.JoinListener; +import me.itsnathang.picturelogin.listeners.QuitListener; import me.itsnathang.picturelogin.util.Hooks; import me.itsnathang.picturelogin.util.PictureUtil; - import me.itsnathang.picturelogin.util.Updater; -import org.bukkit.command.CommandExecutor; -import org.bukkit.plugin.java.JavaPlugin; import org.bstats.bukkit.Metrics; +import org.bukkit.plugin.java.JavaPlugin; +/* +Updated to work with Minecraft 1.18.2 by _NickV on 4/7/2022 + */ public class PictureLogin extends JavaPlugin { - private ConfigManager configManager; - private PictureUtil pictureUtil; + private ConfigManager configManager; + private PictureUtil pictureUtil; - @Override - public void onEnable() { - // load config & languages file - configManager = new ConfigManager(this); + @Override + public void onEnable() { + // load config & languages file + configManager = new ConfigManager(this); - // Register Plugin Hooks - new Hooks(getServer().getPluginManager(), configManager, getLogger()); + // Register Plugin Hooks + new Hooks(getServer().getPluginManager(), configManager, getLogger()); - // Initialize Picture Utility - pictureUtil = new PictureUtil(this); + // Initialize Picture Utility + pictureUtil = new PictureUtil(this); - // register Listeners - getServer().getPluginManager().registerEvents(new JoinListener(this), this); + // register Listeners + getServer().getPluginManager().registerEvents(new JoinListener(this), this); - // (only register leave listener if enabled in config) - if (configManager.getBoolean("show-leave-message", false)) - getServer().getPluginManager().registerEvents(new QuitListener(this), this); + // (only register leave listener if enabled in config) + if (configManager.getBoolean("show-leave-message", false)) { + getServer().getPluginManager().registerEvents(new QuitListener(this), this); + } - // register /picturelogin command - getCommand("picturelogin").setExecutor(new BaseCommand(this)); + // register /picturelogin command + getCommand("picturelogin").setExecutor(new BaseCommand(this)); - // Update Checker - if (configManager.getBoolean("update-check", true)) - new Updater(getLogger(), getDescription().getVersion()); + // Update Checker + if (configManager.getBoolean("update-check", true)) { + new Updater(getLogger(), getDescription().getVersion()); + } - // bStats integration - if (configManager.getBoolean("metrics", true)) - new Metrics(this, 2225); - } + // bStats integration + if (configManager.getBoolean("metrics", true)) { + new Metrics(this, 14892); // 2225 is the bStats plugin ID for PictureLogin + } + } - public ConfigManager getConfigManager() { - return configManager; - } + public ConfigManager getConfigManager() { + return configManager; + } - public PictureUtil getPictureUtil() { - return pictureUtil; - } + public PictureUtil getPictureUtil() { + return pictureUtil; + } } diff --git a/src/main/java/me/itsnathang/picturelogin/commands/BaseCommand.java b/src/main/java/me/itsnathang/picturelogin/commands/BaseCommand.java index 3d12b46..9f497ae 100644 --- a/src/main/java/me/itsnathang/picturelogin/commands/BaseCommand.java +++ b/src/main/java/me/itsnathang/picturelogin/commands/BaseCommand.java @@ -1,43 +1,97 @@ package me.itsnathang.picturelogin.commands; +import me.itsnathang.picturelogin.PictureLogin; +import me.itsnathang.picturelogin.util.PictureUtil; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; -import me.itsnathang.picturelogin.PictureLogin; +import java.util.ArrayList; +import java.util.List; + +import static me.itsnathang.picturelogin.util.Translate.translateString; + +public class BaseCommand implements CommandExecutor, TabCompleter { + private final PictureLogin plugin; + private final PictureUtil util; + + public BaseCommand(PictureLogin plugin) { + this.plugin = plugin; + util = plugin.getPictureUtil(); + } + + @Override + public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { + if (!s.hasPermission("picturelogin.main")) { + s.sendMessage(translateString("no_permission")); + return true; + } + + if (args.length < 1) { + s.sendMessage(ChatColor.GREEN + "PictureLogin " + ChatColor.GRAY + "v" + ChatColor.GREEN + + plugin.getDescription().getVersion() + ChatColor.GRAY + " by " + ChatColor.GREEN + "_NickVo"); + return true; + } + + if (args[0].equalsIgnoreCase("reload")) { + plugin.getConfigManager().reloadConfig(); + s.sendMessage(translateString("reload_config")); + return true; + } + + if (!(s instanceof Player player)) { + s.sendMessage(ChatColor.RED + "The test command can only be ran in-game."); + return true; + } + + // Test command allows admins to test the images they've configured + if (args[0].equalsIgnoreCase("test")) { + if (args.length < 2) { + util.sendImage(player); // If they don't specify another arg, just show join image + return true; + } + + switch (args[1]) { + case "leave" -> util.getLeaveMessage(player).sendToPlayer(player); + case "join" -> util.sendImage(player); + case "first-join" -> util.getFirstJoinMessage(player).sendToPlayer(player); + } + } + + return false; + } + + @Override + public List onTabComplete(CommandSender sender, Command cmd, String label, String[] args) { + if (!sender.hasPermission("picturelogin.main")) { + return List.of(); + } + + if (args.length == 1) { + return getResults(args, List.of("reload", "test")); + } + + // Sub-commands for the test command + if (args.length == 2 && args[0].equalsIgnoreCase("test")) { + return getResults(args, List.of("first-join", "join", "leave")); + } + + return List.of(); // Empty list to stop further tab completion + } + + private List getResults(String[] args, List toSearch) { + List results = new ArrayList<>(); + // This loop narrows down the tab complete results while typing + for (String s : toSearch) { + int index = args.length - 1; + if (s.toLowerCase().startsWith(args[index].toLowerCase())) { + results.add(s); + } + } + return results; + } -import static me.itsnathang.picturelogin.util.Translate.tl; - -public class BaseCommand implements CommandExecutor { - private final PictureLogin plugin; - - // TODO: Remove plugin - public BaseCommand(PictureLogin plugin) { - this.plugin = plugin; - } - - @Override - public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) { - // Permission Check - if (!s.hasPermission("picturelogin.main")) { - s.sendMessage(tl("no_permission")); - return false; - } - - // Check if command is /picturelogin reload - if (args.length == 1 && args[0].equalsIgnoreCase("reload")) { - plugin.getConfigManager().reloadConfig(); - s.sendMessage(tl("reload_config")); - return true; - } - - // Default to sending help - s.sendMessage(ChatColor.GREEN + "PictureLogin " + ChatColor.GRAY + "v" + - ChatColor.GREEN + plugin.getDescription().getVersion() + ChatColor.GRAY + " by " + - ChatColor.GREEN + "NathanG"); - s.sendMessage(tl("reload_config_help")); - - return true; - } } diff --git a/src/main/java/me/itsnathang/picturelogin/config/ConfigManager.java b/src/main/java/me/itsnathang/picturelogin/config/ConfigManager.java index 5da3ded..4209e69 100644 --- a/src/main/java/me/itsnathang/picturelogin/config/ConfigManager.java +++ b/src/main/java/me/itsnathang/picturelogin/config/ConfigManager.java @@ -1,91 +1,92 @@ package me.itsnathang.picturelogin.config; +import com.bobacadodl.imgmessage.ImageChar; +import me.itsnathang.picturelogin.PictureLogin; +import me.itsnathang.picturelogin.util.ImageMessage; +import org.bukkit.configuration.file.YamlConfiguration; + import java.awt.image.BufferedImage; import java.io.File; -import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.logging.Level; -import com.sun.tools.sjavac.Log; -import org.bukkit.configuration.file.YamlConfiguration; +public class ConfigManager { + private final PictureLogin plugin; + private final LanguageManager languageManager; + private YamlConfiguration config; -import com.bobacadodl.imgmessage.ImageChar; -import me.itsnathang.picturelogin.util.ImageMessage; -import me.itsnathang.picturelogin.PictureLogin; + public ConfigManager(PictureLogin plugin) { + this.plugin = plugin; + + languageManager = new LanguageManager(plugin); + reloadConfig(); + } + + public void reloadConfig() { + File conf = new File(plugin.getDataFolder() + File.separator + "config.yml"); + + if (!conf.exists()) { + plugin.saveResource("config.yml", true); // Create new config + } -public class ConfigManager { - private final PictureLogin plugin; - private LanguageManager languageManager; - private YamlConfiguration config; - - public ConfigManager(PictureLogin plugin) { - this.plugin = plugin; - - languageManager = new LanguageManager(plugin); - - reloadConfig(); - } - - public void reloadConfig() { - File conf = new File(plugin.getDataFolder() + File.separator + "config.yml"); - - if(!conf.exists()) - plugin.saveResource("config.yml", true); - config = YamlConfiguration.loadConfiguration(conf); + languageManager.reloadLanguage(); + } + + private char getChar() { + try { + return ImageChar.valueOf(config.getString("character").toUpperCase()).getChar(); + } catch (IllegalArgumentException e) { + return ImageChar.BLOCK.getChar(); + } + } + + public ImageMessage getMessage(List messages, BufferedImage image) { + int imageDimensions = 8, count = 0; + + ImageMessage imageMessage = new ImageMessage(image, imageDimensions, getChar()); + String[] msg = new String[imageDimensions]; + + for (String message : messages) { + if (count > msg.length) { + break; + } + msg[count++] = message; + } + + while (count < imageDimensions) { + msg[count++] = ""; + } + + if (config.getBoolean("center-text", false)) { + return imageMessage.appendCenteredText(msg); + } else { + return imageMessage.appendText(msg); + } + } + + public long getLong(String key) { + return config.getLong(key); + } + + public boolean getBoolean(String key, Boolean def) { + return config.getBoolean(key, def); + } + + public List getStringList(String key) { + return config.getStringList(key); + } + + public String getURL() { + String url = config.getString("url"); + + if (url == null) { + plugin.getLogger().log(Level.SEVERE, "Could not read picture url from config.yml!"); + + return "https://minepic.org/avatar/8/%uuid%"; + } + + return url; + } - languageManager.reloadLanguage(); - } - - private char getChar() { - try { - return ImageChar.valueOf(config.getString("character").toUpperCase()).getChar(); - } catch (IllegalArgumentException e) { - return ImageChar.BLOCK.getChar(); - } - } - - public ImageMessage getMessage(List messages, BufferedImage image) { - int imageDimensions = 8, count = 0; - ImageMessage imageMessage = new ImageMessage(image, imageDimensions, getChar()); - String[] msg = new String[imageDimensions]; - - for (String message : messages) { - if (count > msg.length) break; - msg[count++] = message; - } - - while (count < imageDimensions) { - msg[count++] = ""; - } - - if (config.getBoolean("center-text", false)) - return imageMessage.appendCenteredText(msg); - - return imageMessage.appendText(msg); - } - - public boolean getBoolean(String key) { - return config.getBoolean(key); - } - - public boolean getBoolean(String key, Boolean def) { return config.getBoolean(key, def); } - - public List getStringList(String key) { - return config.getStringList(key); - } - - public String getURL() { - String url = config.getString("url"); - - if (url == null) { - plugin.getLogger().log(Level.SEVERE, "Could not read picture url from config.yml!"); - - return "https://minepic.org/avatar/8/%uuid%"; - } - - return url; - } - } diff --git a/src/main/java/me/itsnathang/picturelogin/config/FallbackPicture.java b/src/main/java/me/itsnathang/picturelogin/config/FallbackPicture.java index 8a2c81c..d189758 100644 --- a/src/main/java/me/itsnathang/picturelogin/config/FallbackPicture.java +++ b/src/main/java/me/itsnathang/picturelogin/config/FallbackPicture.java @@ -15,16 +15,11 @@ public File get() { final String FALLBACK_PATH = plugin.getDataFolder() + File.separator + "fallback.png"; File image = new File(FALLBACK_PATH); - - if (!image.exists()) + if (!image.exists()) { plugin.saveResource("fallback.png", false); + } - if (plugin.getConfigManager().getBoolean("fallback", true)) - image = new File(FALLBACK_PATH); - else - image = null; - - return image; + return plugin.getConfigManager().getBoolean("fallback", true) ? new File(FALLBACK_PATH) : null; } } diff --git a/src/main/java/me/itsnathang/picturelogin/config/LanguageManager.java b/src/main/java/me/itsnathang/picturelogin/config/LanguageManager.java index 3ac9a4d..d3247e4 100644 --- a/src/main/java/me/itsnathang/picturelogin/config/LanguageManager.java +++ b/src/main/java/me/itsnathang/picturelogin/config/LanguageManager.java @@ -7,7 +7,7 @@ import java.io.File; public class LanguageManager { - private PictureLogin plugin; + private final PictureLogin plugin; LanguageManager(PictureLogin plugin) { this.plugin = plugin; @@ -16,18 +16,16 @@ public class LanguageManager { } private YamlConfiguration loadLanguage() { - File language_file = new File(plugin.getDataFolder() + File.separator + "messages.yml"); + File yml = new File(plugin.getDataFolder() + File.separator + "messages.yml"); - if (!language_file.exists()) + if (!yml.exists()) { plugin.saveResource("messages.yml", false); - - return YamlConfiguration.loadConfiguration(language_file); + } + return YamlConfiguration.loadConfiguration(yml); } public void reloadLanguage() { - YamlConfiguration messages = loadLanguage(); - - Translate.messages = messages; + Translate.messages = loadLanguage(); } } diff --git a/src/main/java/me/itsnathang/picturelogin/listeners/JoinListener.java b/src/main/java/me/itsnathang/picturelogin/listeners/JoinListener.java index 69dbcdc..a0102ea 100644 --- a/src/main/java/me/itsnathang/picturelogin/listeners/JoinListener.java +++ b/src/main/java/me/itsnathang/picturelogin/listeners/JoinListener.java @@ -1,72 +1,80 @@ package me.itsnathang.picturelogin.listeners; import fr.xephi.authme.api.v3.AuthMeApi; +import me.itsnathang.picturelogin.PictureLogin; +import me.itsnathang.picturelogin.config.ConfigManager; import me.itsnathang.picturelogin.util.Hooks; -import me.itsnathang.picturelogin.util.PictureWrapper; +import me.itsnathang.picturelogin.util.PictureUtil; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; - -import me.itsnathang.picturelogin.PictureLogin; -import me.itsnathang.picturelogin.config.ConfigManager; -import me.itsnathang.picturelogin.util.PictureUtil; import org.bukkit.scheduler.BukkitRunnable; public class JoinListener implements Listener { - private PictureLogin plugin; - private PictureUtil pictureUtil; - private ConfigManager config; - private Player player; - - public JoinListener(PictureLogin plugin) { - this.plugin = plugin; - this.config = plugin.getConfigManager(); - this.pictureUtil = plugin.getPictureUtil(); - } - - @EventHandler (priority = EventPriority.HIGH) - public void onJoin(PlayerJoinEvent event) { - this.player = event.getPlayer(); - - // block the default join message - if (config.getBoolean("block-join-message", false)) - event.setJoinMessage(null); - - if (Hooks.AUTHME) { - authMeLogin(); - return; - } - - sendImage(); - } - - private void authMeLogin() { - new BukkitRunnable() { - - @Override - public void run() { - // Stop if player left the server - if (player == null || !player.isOnline()) - this.cancel(); - - // Check for authentication - if (AuthMeApi.getInstance().isAuthenticated(player)) { - sendImage(); - this.cancel(); - } - } - - }.runTaskTimer(plugin, 0L, 20L); - } - - private void sendImage() { - PictureWrapper wrapper = new PictureWrapper(plugin, player); - - if (config.getBoolean("async", true)) - wrapper.runTaskAsynchronously(plugin); - else - wrapper.runTask(plugin); - } + private final PictureLogin plugin; + private final ConfigManager config; + private final PictureUtil utils; + private Player player; + + public JoinListener(PictureLogin plugin) { + this.plugin = plugin; + this.config = plugin.getConfigManager(); + this.utils = plugin.getPictureUtil(); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onJoin(PlayerJoinEvent event) { + this.player = event.getPlayer(); + + // block the default join message + if (config.getBoolean("block-join-message", false)) { + event.setJoinMessage(null); + } + + if (Hooks.AUTHME) { + authMeLogin(); + } else { + utils.sendImage(player); + } + } + + private void authMeLogin() { + new BukkitRunnable() { + @Override + public void run() { + // Stop if player left the server + if (player == null || !player.isOnline()) { + this.cancel(); + } + + // Check for authentication + if (AuthMeApi.getInstance().isAuthenticated(player)) { + utils.sendImage(player); + this.cancel(); + } + } + + }.runTaskTimer(plugin, 0L, 20L); + } + } + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/me/itsnathang/picturelogin/listeners/QuitListener.java b/src/main/java/me/itsnathang/picturelogin/listeners/QuitListener.java index ef017db..a37fed0 100644 --- a/src/main/java/me/itsnathang/picturelogin/listeners/QuitListener.java +++ b/src/main/java/me/itsnathang/picturelogin/listeners/QuitListener.java @@ -1,42 +1,43 @@ package me.itsnathang.picturelogin.listeners; -import me.itsnathang.picturelogin.util.ImageMessage; import me.itsnathang.picturelogin.PictureLogin; +import me.itsnathang.picturelogin.config.ConfigManager; +import me.itsnathang.picturelogin.util.ImageMessage; +import me.itsnathang.picturelogin.util.PictureUtil; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; -import me.itsnathang.picturelogin.config.ConfigManager; -import me.itsnathang.picturelogin.util.PictureUtil; - public class QuitListener implements Listener { - private PictureUtil pictureUtil; - private ConfigManager config; - - public QuitListener(PictureLogin plugin) { - this.config = plugin.getConfigManager(); - this.pictureUtil = plugin.getPictureUtil(); - } - - @EventHandler - public void onQuit(PlayerQuitEvent event) { - if (!config.getBoolean("show-leave-message", true)) - return; - - Player player = event.getPlayer(); - - if(!player.hasPermission("picturelogin.show") && config.getBoolean("require-permission", true)) - return; - - if (config.getBoolean("block-leave-message", true)) - event.setQuitMessage(null); - - ImageMessage picture_message = pictureUtil.createPictureMessage(player, config.getStringList("leave-messages")); - - if (picture_message == null) return; - - pictureUtil.sendOutPictureMessage(picture_message); - } + private final PictureUtil pictureUtil; + private final ConfigManager config; + + public QuitListener(PictureLogin plugin) { + this.config = plugin.getConfigManager(); + this.pictureUtil = plugin.getPictureUtil(); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) { + if (!config.getBoolean("show-leave-message", true)) + return; + + Player player = event.getPlayer(); + if (!player.hasPermission("picturelogin.show") && config.getBoolean("require-permission", true)) { + return; + } + + if (config.getBoolean("block-leave-message", true)) { + event.setQuitMessage(null); + } + + ImageMessage picture_message = pictureUtil.getLeaveMessage(player); + if (picture_message == null) { + return; + } + + pictureUtil.sendOutPictureMessage(picture_message); + } } diff --git a/src/main/java/me/itsnathang/picturelogin/util/DefaultFontInfo.java b/src/main/java/me/itsnathang/picturelogin/util/DefaultFontInfo.java new file mode 100644 index 0000000..be87844 --- /dev/null +++ b/src/main/java/me/itsnathang/picturelogin/util/DefaultFontInfo.java @@ -0,0 +1,130 @@ +package me.itsnathang.picturelogin.util; + +public enum DefaultFontInfo { + A('A', 5), + a('a', 5), + B('B', 5), + b('b', 5), + C('C', 5), + c('c', 5), + D('D', 5), + d('d', 5), + E('E', 5), + e('e', 5), + F('F', 5), + f('f', 4), + G('G', 5), + g('g', 5), + H('H', 5), + h('h', 5), + I('I', 3), + i('i', 1), + J('J', 5), + j('j', 5), + K('K', 5), + k('k', 4), + L('L', 5), + l('l', 1), + M('M', 5), + m('m', 5), + N('N', 5), + n('n', 5), + O('O', 5), + o('o', 5), + P('P', 5), + p('p', 5), + Q('Q', 5), + q('q', 5), + R('R', 5), + r('r', 5), + S('S', 5), + s('s', 5), + T('T', 5), + t('t', 4), + U('U', 5), + u('u', 5), + V('V', 5), + v('v', 5), + W('W', 5), + w('w', 5), + X('X', 5), + x('x', 5), + Y('Y', 5), + y('y', 5), + Z('Z', 5), + z('z', 5), + NUM_1('1', 5), + NUM_2('2', 5), + NUM_3('3', 5), + NUM_4('4', 5), + NUM_5('5', 5), + NUM_6('6', 5), + NUM_7('7', 5), + NUM_8('8', 5), + NUM_9('9', 5), + NUM_0('0', 5), + EXCLAMATION_POINT('!', 1), + AT_SYMBOL('@', 6), + NUM_SIGN('#', 5), + DOLLAR_SIGN('$', 5), + PERCENT('%', 5), + UP_ARROW('^', 5), + AMPERSAND('&', 5), + ASTERISK('*', 5), + LEFT_PARENTHESIS('(', 4), + RIGHT_PARENTHESIS(')', 4), + MINUS('-', 5), + UNDERSCORE('_', 5), + PLUS_SIGN('+', 5), + EQUALS_SIGN('=', 5), + LEFT_CURL_BRACE('{', 4), + RIGHT_CURL_BRACE('}', 4), + LEFT_BRACKET('[', 3), + RIGHT_BRACKET(']', 3), + COLON(':', 1), + SEMI_COLON(';', 1), + DOUBLE_QUOTE('"', 3), + SINGLE_QUOTE('\'', 1), + LEFT_ARROW('<', 4), + RIGHT_ARROW('>', 4), + QUESTION_MARK('?', 5), + SLASH('/', 5), + BACK_SLASH('\\', 5), + LINE('|', 1), + TILDE('~', 5), + TICK('`', 2), + PERIOD('.', 1), + COMMA(',', 1), + SPACE(' ', 3), + DEFAULT('a', 4); + + private final char character; + private final int length; + + DefaultFontInfo(char character, int length) { + this.character = character; + this.length = length; + } + + public char getCharacter() { + return this.character; + } + + public int getLength() { + return this.length; + } + + public int getBoldLength() { + if (this == DefaultFontInfo.SPACE) { + return this.getLength(); + } + return this.length + 1; + } + + public static DefaultFontInfo getDefaultFontInfo(char c) { + for (DefaultFontInfo dFI : DefaultFontInfo.values()) { + if (dFI.getCharacter() == c) return dFI; + } + return DefaultFontInfo.DEFAULT; + } +} diff --git a/src/main/java/me/itsnathang/picturelogin/util/Hooks.java b/src/main/java/me/itsnathang/picturelogin/util/Hooks.java index 9563918..b7a5873 100644 --- a/src/main/java/me/itsnathang/picturelogin/util/Hooks.java +++ b/src/main/java/me/itsnathang/picturelogin/util/Hooks.java @@ -6,9 +6,9 @@ import java.util.logging.Logger; public class Hooks { - private PluginManager plugins; - private ConfigManager config; - private Logger logger; + private final PluginManager plugins; + private final ConfigManager config; + private final Logger logger; public static boolean AUTHME; public static boolean PLACEHOLDER_API; @@ -18,27 +18,22 @@ public Hooks(PluginManager plugins, ConfigManager config, Logger logger) { this.config = config; this.logger = logger; - hookAuthMe(); - hookPlaceHolderAPI(); + AUTHME = hookPlugin("AuthMe"); + PLACEHOLDER_API = hookPlugin("PlaceholderAPI"); } private boolean hookPlugin(String plugin) { - if (!plugins.isPluginEnabled(plugin)) + if (!plugins.isPluginEnabled(plugin)) { return false; + } // Make sure user wants to hook into the plugin - if (!config.getBoolean("hooks." + plugin, true)) + if (!config.getBoolean("hooks." + plugin, true)) { return false; + } logger.info(() -> "Hooked into: " + plugin); return true; } - private void hookAuthMe() { - AUTHME = hookPlugin("AuthMe"); - } - - private void hookPlaceHolderAPI() { - PLACEHOLDER_API = hookPlugin("PlaceholderAPI"); - } } diff --git a/src/main/java/me/itsnathang/picturelogin/util/ImageMessage.java b/src/main/java/me/itsnathang/picturelogin/util/ImageMessage.java index 659fa43..251a87c 100644 --- a/src/main/java/me/itsnathang/picturelogin/util/ImageMessage.java +++ b/src/main/java/me/itsnathang/picturelogin/util/ImageMessage.java @@ -1,20 +1,20 @@ package me.itsnathang.picturelogin.util; import de.themoep.minedown.MineDown; +import me.itsnathang.picturelogin.PictureLogin; import org.bukkit.ChatColor; import org.bukkit.entity.Player; -import org.bukkit.util.ChatPaginator; -import java.awt.*; +import java.awt.Color; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; +import java.util.logging.Level; public class ImageMessage { private final static char TRANSPARENT_CHAR = ' '; - - private String[] lines; - + private String[] lines; // The 8 lines next to the playerhead + public ImageMessage(BufferedImage image, int height, char imgChar) { Color[][] chatColors = toChatColorArray(image, height); lines = toImgMessage(chatColors, imgChar); @@ -38,9 +38,11 @@ private Color[][] toChatColorArray(BufferedImage image, int height) { private BufferedImage resizeImage(BufferedImage originalImage, int width, int height) { AffineTransform af = new AffineTransform(); - af.scale( - width / (double) originalImage.getWidth(), - height / (double) originalImage.getHeight()); + + double newWidth = width / (double) originalImage.getWidth(); + double newHeight = height / (double) originalImage.getHeight(); + + af.scale(newWidth, newHeight); AffineTransformOp operation = new AffineTransformOp(af, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); return operation.filter(originalImage, null); @@ -48,28 +50,24 @@ private BufferedImage resizeImage(BufferedImage originalImage, int width, int he private String[] toImgMessage(Color[][] colors, char imgchar) { lines = new String[colors[0].length]; - + for (int y = 0; y < colors[0].length; y++) { StringBuilder line = new StringBuilder(); - for (int x = 0; x < colors.length; x++) { - Color color = colors[x][y]; + for (Color[] value : colors) { + Color color = value[y]; // convert to minedown-styled color string if (color != null) { - line.append("&") - .append(colorToHex(colors[x][y])) - .append("&") - .append(imgchar); - } - else { + line.append("&").append(colorToHex(value[y])).append("&").append(imgchar); + } else { line.append(TRANSPARENT_CHAR); } } lines[y] = line.toString() + ChatColor.RESET; } - + return lines; } - + private String colorToHex(Color c) { return String.format("#%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue()); } @@ -86,8 +84,7 @@ public ImageMessage appendText(String... text) { public ImageMessage appendCenteredText(String... text) { for (int y = 0; y < lines.length; y++) { if (text.length > y) { - int len = ChatPaginator.AVERAGE_CHAT_PAGE_WIDTH - lines[y].length(); - lines[y] = lines[y] + center(text[y], len); + lines[y] += centerMessage(text[y]); } else { return this; } @@ -95,19 +92,55 @@ public ImageMessage appendCenteredText(String... text) { return this; } - private String center(String s, int length) { - if (s.length() > length) { - return s.substring(0, length); - } else if (s.length() == length) { - return s; - } else { - int leftPadding = (length - s.length()) / 2; - StringBuilder leftBuilder = new StringBuilder(); - for (int i = 0; i < leftPadding; i++) { - leftBuilder.append(" "); + /* + Credit to https://www.spigotmc.org/members/sirspoodles.109063/ for this method + https://www.spigotmc.org/threads/free-code-sending-perfectly-centered-chat-message.95872/ + */ + public String centerMessage(String message) { + if (message == null || message.equals("")) { + message = ""; + } + + message = ChatColor.translateAlternateColorCodes('&', message); + + int messagePxSize = 0; + boolean previousCode = false; + boolean isBold = false; + + for (char c : message.toCharArray()) { + if (c == '§') { + previousCode = true; + } else if (previousCode) { + previousCode = false; + isBold = c == 'l' || c == 'L'; + } else { + var dFI = DefaultFontInfo.getDefaultFontInfo(c); + messagePxSize += isBold ? dFI.getBoldLength() : dFI.getLength(); + messagePxSize++; + } + } + + int halvedMessageSize = messagePxSize / 2; + int CENTER_PX = 154; + int toCompensate = CENTER_PX - halvedMessageSize; + int spaceLength = DefaultFontInfo.SPACE.getLength() + 1; + int compensated = 0; + + StringBuilder sb = new StringBuilder(); + while (compensated < toCompensate) { + sb.append(" "); + compensated += spaceLength; + } + + int offset = 8; // account for the player head (8 wide) + for (int j = 0; j < offset; j++) { + int anIndex = sb.length() - 1; + if (anIndex >= 0) { + sb.deleteCharAt(anIndex); } - return leftBuilder.toString() + s; } + + return sb + message; } public void sendToPlayer(Player player) { @@ -115,4 +148,5 @@ public void sendToPlayer(Player player) { player.spigot().sendMessage(MineDown.parse(line)); } } + } diff --git a/src/main/java/me/itsnathang/picturelogin/util/PictureUtil.java b/src/main/java/me/itsnathang/picturelogin/util/PictureUtil.java index a1dfde0..64dc6e1 100644 --- a/src/main/java/me/itsnathang/picturelogin/util/PictureUtil.java +++ b/src/main/java/me/itsnathang/picturelogin/util/PictureUtil.java @@ -1,16 +1,5 @@ package me.itsnathang.picturelogin.util; -import static me.itsnathang.picturelogin.util.Translate.tl; - -import java.awt.image.BufferedImage; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.util.List; - -import javax.imageio.ImageIO; - -import me.itsnathang.picturelogin.util.ImageMessage; import me.clip.placeholderapi.PlaceholderAPI; import me.itsnathang.picturelogin.PictureLogin; import me.itsnathang.picturelogin.config.ConfigManager; @@ -18,94 +7,132 @@ import org.bukkit.ChatColor; import org.bukkit.entity.Player; +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.List; + +import static me.itsnathang.picturelogin.util.Translate.translateString; + public class PictureUtil { - private final PictureLogin plugin; - private ConfigManager config; - - public PictureUtil(PictureLogin plugin) { - this.plugin = plugin; - this.config = plugin.getConfigManager(); - } - - private URL newURL(String player_uuid, String player_name) { - String url = config.getURL() - .replace("%uuid%" , player_uuid) - .replace("%pname%", player_name); - - try { - return new URL(url); - } catch (Exception e) { - plugin.getLogger().warning("Could not read url from file."); - return null; - } - } - - private BufferedImage getImage(Player player) { - URL head_image = newURL(player.getUniqueId().toString(), player.getName()); - - // URL Formatted correctly. - if (head_image != null) { + private final PictureLogin plugin; + private final ConfigManager config; + + public PictureUtil(PictureLogin plugin) { + this.plugin = plugin; + this.config = plugin.getConfigManager(); + } + + private URL newURL(String player_uuid, String player_name) { + String url = config.getURL() + .replace("%uuid%", player_uuid) + .replace("%pname%", player_name); + try { + return new URL(url); + } catch (Exception e) { + plugin.getLogger().warning("Could not read url from file."); + return null; + } + } + + private BufferedImage getImage(Player player) { + URL head_image = newURL(player.getUniqueId().toString(), player.getName()); + + // URL Formatted correctly. + if (head_image != null) { try { - //User-Agent is needed for HTTP requests - HttpURLConnection connection = (HttpURLConnection) head_image.openConnection(); - connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11"); + //User-Agent is needed for HTTP requests + HttpURLConnection connection = (HttpURLConnection) head_image.openConnection(); + connection.setRequestProperty("User-Agent", + "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11"); return ImageIO.read(connection.getInputStream()); } catch (Exception e) { - e.printStackTrace(); - plugin.getLogger().warning(tl("error_retrieving_avatar")); + e.printStackTrace(); + plugin.getLogger().warning(translateString("error_retrieving_avatar")); } - } - - // Incorrectly formatted URL or couldn't load from URL - try { - return ImageIO.read(new FallbackPicture(plugin).get()); - } catch (Exception e) { - plugin.getLogger().warning(tl("error_fallback_img")); - return null; - } - } - - public ImageMessage createPictureMessage(Player player, List messages) { - BufferedImage image = getImage(player); - - if (image == null) return null; - - messages.replaceAll((message) -> addPlaceholders(message, player)); - - return config.getMessage(messages, image); - } - - public void sendOutPictureMessage(ImageMessage picture_message) { - plugin.getServer().getOnlinePlayers().forEach((online_player) -> { - if (config.getBoolean("clear-chat", false)) - clearChat(online_player); - - picture_message.sendToPlayer(online_player); - }); - } - - // String Utility Functions - - private String addPlaceholders(String msg, Player player) { - msg = ChatColor.translateAlternateColorCodes('&', msg); - - msg = msg.replace("%pname%", player.getName()); - msg = msg.replace("%uuid%", player.getUniqueId().toString()); - msg = msg.replace("%online%", String.valueOf(plugin.getServer().getOnlinePlayers().size())); - msg = msg.replace("%max%", String.valueOf(plugin.getServer().getMaxPlayers())); - msg = msg.replace("%motd%", plugin.getServer().getMotd()); - msg = msg.replace("%displayname%", player.getDisplayName()); - - if (Hooks.PLACEHOLDER_API) - msg = PlaceholderAPI.setPlaceholders(player, msg); - - return msg; - } - - public void clearChat(Player player) { - for (int i = 0; i < 20; i++) { - player.sendMessage(""); - } - } + } + + // Incorrectly formatted URL, or couldn't load from URL + try { + return ImageIO.read(new FallbackPicture(plugin).get()); + } catch (Exception e) { + plugin.getLogger().warning(translateString("error_fallback_img")); + return null; + } + } + + public ImageMessage createPictureMessage(Player player, List messages) { + BufferedImage image = getImage(player); + + if (image == null) { + return null; + } + + messages.replaceAll((message) -> addPlaceholders(message, player)); + + return config.getMessage(messages, image); + } + + public void sendOutPictureMessage(ImageMessage picture_message) { + plugin.getServer().getOnlinePlayers().forEach((online_player) -> { + if (config.getBoolean("clear-chat", false)) { + clearChat(online_player); + } + + picture_message.sendToPlayer(online_player); + }); + } + + public void sendImage(Player player) { + PictureWrapper wrapper = new PictureWrapper(plugin, player); + + long delay = config.getLong("message-delay"); + + // Don't allow invalid number here + if (delay < 0) { + delay = 0; + } + + if (config.getBoolean("async", true)) { + wrapper.runTaskLaterAsynchronously(plugin, delay); + } else { + wrapper.runTaskLater(plugin, delay); + } + } + + public ImageMessage getLeaveMessage(Player player) { + List list = config.getStringList("leave-messages"); + return createPictureMessage(player, list); + } + + public ImageMessage getFirstJoinMessage(Player player) { + List list = plugin.getConfigManager().getStringList("first-join-messages"); + return createPictureMessage(player, list); + } + + private String addPlaceholders(String msg, Player player) { + if (Hooks.PLACEHOLDER_API) { + msg = PlaceholderAPI.setPlaceholders(player, msg); + } + + msg = Translate.translateHexColor(msg); + msg = ChatColor.translateAlternateColorCodes('&', msg); + + msg = msg.replace("%pname%", player.getName()); + msg = msg.replace("%uuid%", player.getUniqueId().toString()); + msg = msg.replace("%online%", String.valueOf(plugin.getServer().getOnlinePlayers().size())); + msg = msg.replace("%max%", String.valueOf(plugin.getServer().getMaxPlayers())); + msg = msg.replace("%motd%", plugin.getServer().getMotd()); + msg = msg.replace("%displayname%", player.getDisplayName()); + + return msg; + } + + public void clearChat(Player player) { + for (int i = 0; i < 20; i++) { + player.sendMessage(""); + } + } } diff --git a/src/main/java/me/itsnathang/picturelogin/util/PictureWrapper.java b/src/main/java/me/itsnathang/picturelogin/util/PictureWrapper.java index 318a954..6134c17 100644 --- a/src/main/java/me/itsnathang/picturelogin/util/PictureWrapper.java +++ b/src/main/java/me/itsnathang/picturelogin/util/PictureWrapper.java @@ -1,64 +1,60 @@ package me.itsnathang.picturelogin.util; -import me.itsnathang.picturelogin.util.ImageMessage; import me.itsnathang.picturelogin.PictureLogin; import me.itsnathang.picturelogin.config.ConfigManager; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; public class PictureWrapper extends BukkitRunnable { - private PictureUtil pictureUtil; - private ConfigManager config; - private Player player; + private final PictureUtil pictureUtil; + private final ConfigManager config; + private final Player player; public PictureWrapper(PictureLogin plugin, Player player) { this.pictureUtil = plugin.getPictureUtil(); - this.config = plugin.getConfigManager(); - this.player = player; + this.config = plugin.getConfigManager(); + this.player = player; } @Override public void run() { - sendImage(); + if (!checkPermission()) { // only show message for players with picturelogin.show permission + return; + } + + ImageMessage pictureMessage = getMessage(); + if (pictureMessage == null) { + return; + } + + // send only to the player that joined? + if (config.getBoolean("player-only", true)) { + if (config.getBoolean("clear-chat", false)) { + pictureUtil.clearChat(player); + } + + pictureMessage.sendToPlayer(player); + return; + } + + pictureUtil.sendOutPictureMessage(pictureMessage); } private boolean checkPermission() { - if (!config.getBoolean("require-permission", true)) + if (!config.getBoolean("require-permission", true)) { return true; + } return player.hasPermission("picturelogin.show"); } private ImageMessage getMessage() { - String msgType; + boolean firstTime = config.getBoolean("show-first-join", true) && !player.hasPlayedBefore(); // if it's a player's first time and feature is enabled, show different message - if (config.getBoolean("show-first-join", true) && !player.hasPlayedBefore()) - msgType = "first-join-messages"; - else - msgType = "messages"; + String msgType = firstTime ? "first-join-messages" : "messages"; return pictureUtil.createPictureMessage(player, config.getStringList(msgType)); } - private void sendImage() { - // only show message for players with picturelogin.show permission - if(!checkPermission()) return; - - ImageMessage pictureMessage = getMessage(); - - if (pictureMessage == null) return; - - // send only to the player that joined? - if (config.getBoolean("player-only", true)) { - if (config.getBoolean("clear-chat", false)) - pictureUtil.clearChat(player); - - pictureMessage.sendToPlayer(player); - return; - } - - pictureUtil.sendOutPictureMessage(pictureMessage); - } - } diff --git a/src/main/java/me/itsnathang/picturelogin/util/Translate.java b/src/main/java/me/itsnathang/picturelogin/util/Translate.java index 5b7149c..9dd848c 100644 --- a/src/main/java/me/itsnathang/picturelogin/util/Translate.java +++ b/src/main/java/me/itsnathang/picturelogin/util/Translate.java @@ -1,8 +1,11 @@ package me.itsnathang.picturelogin.util; -import org.bukkit.ChatColor; +import net.md_5.bungee.api.ChatColor; import org.bukkit.configuration.file.YamlConfiguration; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class Translate { public static YamlConfiguration messages; @@ -10,22 +13,33 @@ private Translate() { throw new IllegalStateException("Utility Class"); } - public static String tl(String key) { - return translate(key); - } + public static String translateString(String key) { + final String message = messages.getString(key) + .replace("%prefix%", messages.getString("prefix")) + .replace("%new_line%", "\n"); - private static String translate(String key) { - return getFilteredTranslation(key); + return ChatColor.translateAlternateColorCodes('&', message); } - private static String getFilteredTranslation(String key) { - return color(messages.getString(key) - .replace("%prefix%", messages.getString("prefix")) - .replace("%new_line%", "\n")); - } + public static String translateHexColor(final String message) { + final char colorChar = ChatColor.COLOR_CHAR; - private static String color(String message) { - return ChatColor.translateAlternateColorCodes('&', message); + // Added optional catch for & because some plugins (Essentials?) require + // or allow the & symbol before hex. + Pattern pattern = Pattern.compile("&?#([a-fA-F0-9]{6})"); + final Matcher matcher = pattern.matcher(message); + final StringBuilder buffer = new StringBuilder(message.length() + 4 * 8); + + while (matcher.find()) { + final String group = matcher.group(1); + + matcher.appendReplacement(buffer, colorChar + "x" + + colorChar + group.charAt(0) + colorChar + group.charAt(1) + + colorChar + group.charAt(2) + colorChar + group.charAt(3) + + colorChar + group.charAt(4) + colorChar + group.charAt(5)); + } + + return matcher.appendTail(buffer).toString(); } } diff --git a/src/main/java/me/itsnathang/picturelogin/util/Updater.java b/src/main/java/me/itsnathang/picturelogin/util/Updater.java index 73a371a..075bed7 100644 --- a/src/main/java/me/itsnathang/picturelogin/util/Updater.java +++ b/src/main/java/me/itsnathang/picturelogin/util/Updater.java @@ -8,32 +8,34 @@ import java.net.URL; import java.util.logging.Logger; -import static me.itsnathang.picturelogin.util.Translate.tl; +import static me.itsnathang.picturelogin.util.Translate.translateString; public class Updater { - public Updater(Logger log, String currentVersion) { + public Updater(Logger log, String currentVersion) { final String USER_AGENT = "PictureLogin Plugin"; - final String PLUGIN_ID = "4514"; + final String PLUGIN_ID = "101216"; // This is the Spigot plugin ID try { // Connect to SpiGet URL url = new URL("https://api.spiget.org/v2/resources/" + PLUGIN_ID + "/versions/latest"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.addRequestProperty("User-Agent", USER_AGENT);// Set User-Agent + // Read downloaded file - JsonObject jsonObject = new JsonParser().parse(new InputStreamReader(connection.getInputStream())).getAsJsonObject(); + var streamReader = new InputStreamReader(connection.getInputStream()); + JsonObject jsonObject = new JsonParser().parse(streamReader).getAsJsonObject(); String latest_version = jsonObject.get("name").toString().replace("\"", ""); // Compare current plugin version with downloaded one if (!currentVersion.equalsIgnoreCase(latest_version)) { - log.info(tl("update_available").replace("%current%", currentVersion).replace("%new%", latest_version)); - log.info(tl("update_available_download")); + log.info(translateString("update_available").replace("%current%", currentVersion).replace("%new%", latest_version)); + log.info(translateString("update_available_download")); } } catch (Exception e) { - log.warning(tl("error_update_check")); + log.warning(translateString("error_update_check")); } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 6360dde..44d315d 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -13,8 +13,7 @@ # Messsages ######## # Each message is a line, leave blank for a blank line -# (If image height is 8, you can have eight lines; etc.) -# Chat codes supported. +# Chat codes supported ######## # Variables: # %pname% - Joined player's name (no formatting) @@ -22,10 +21,13 @@ # %max% - Maximum players # %motd% - MOTD # %displayname% - Joined player's display name + ######## # NOTE: You may also use variables from the plugin # PlaceholderAPI if it is installed. +# Do not add additional messages to this list! +# Max of 8 allowed (that's the length of the player head image) messages: - '' - '&7Welcome to &e&lGeneric Server Name&7!' @@ -45,6 +47,7 @@ messages: show-first-join: true +# Do not add additional messages to this list - Max of 8 allowed first-join-messages: - '' - '&7Welcome to &e&lGeneric Server Name&7!' @@ -65,6 +68,7 @@ first-join-messages: show-leave-message: false +# Do not add additional messages to this list - Max of 8 allowed leave-messages: - '' - '&e%pname% &7has left the server!' @@ -75,6 +79,17 @@ leave-messages: - '&7» &aPictureLogin &7by &aNathanG&7.' - '' +############# +# Message delay +######## +# Whether to delay the sending of all picture messages. +# +# This delay is in server ticks! For reference, there are 20 server ticks in 1 second. +# +# For example: To set a delay of 2 seconds, set message-delay to 40. + +message-delay: 0 + ############# # Fallback ######## @@ -98,8 +113,7 @@ clear-chat: false ############# # Center Text ######## -# Whether or not to center -# the text beside the image. +# Whether to center the text beside the image. # Acceptable: [true|false] center-text: false @@ -141,7 +155,7 @@ character: 'BLOCK' # URL ######## # Where to get the picture from. -# By default it uses crafatar. +# By default, this is set to minepic.org # You should probably leave this where it is. ######## # Variables: diff --git a/src/main/resources/fallback.png b/src/main/resources/fallback.png index 3982c61..6992369 100644 Binary files a/src/main/resources/fallback.png and b/src/main/resources/fallback.png differ diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml index c89f37f..c749ce3 100644 --- a/src/main/resources/messages.yml +++ b/src/main/resources/messages.yml @@ -13,10 +13,10 @@ no_permission: "%prefix% &cYou do not have permission to do this!" # Misc update_available: "New update available! Current Version: %current% New Version: %new%" -update_available_download: "Download at https://www.spigotmc.org/resources/picture-login.4514/" +update_available_download: "Download at https://www.spigotmc.org/resources/picturelogin-continued.101216/" # Error Messages (Printed in console.) error_reload_config: "Could not access the configuration file." -error_retrieving_avatar: "Could not retrieve avatar from URL. Reverting to fallback image." +error_retrieving_avatar: "Could not retrieve avatar from URL. Reverting to fallback image. Cracked servers: Make sure you're using %pname% in the config." error_fallback_img: "Could not load fallback image." error_update_check: "Could not check for update." \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 3517d01..d13b6af 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: PictureLogin main: me.itsnathang.picturelogin.PictureLogin -api-version: 1.16 -author: NathanG +api-version: 1.19 +author: NathanG, _NickV description: Display a cool login message with a picture of the player's skin. version: ${version}