All source projects

MrUltimateLibrary Source

Standalone source project / 68 files

MrUltimateLibrary is the backbone of all my plugins; it offers features that facilitate plugin creation, maintenance, and updates.

java

MrUltimateLibrary/src/main/java/eu/mrneznamy/mrultimatelibrary/messages/MrLibMessage.java

JAVA · Read-only source

package eu.mrneznamy.mrultimatelibrary.messages;

import eu.mrneznamy.mrultimatelibrary.actionbar.MrLibActionBar;
import eu.mrneznamy.mrultimatelibrary.title.MrLibTitle;
import eu.mrneznamy.mrultimatelibrary.utils.MrLibColors;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Advanced message system with multiple display types
 *
 * Supports:
 * (!message!) - Chat message
 * (!title!) - Title
 * (!subtitle!) - Subtitle
 * (!actionbar!) - ActionBar
 * (!hover:TEXT!) - Hover message
 * (!click:COMMAND!) - Click command
 * (!sound:SOUND!) - Play sound to player
 * (!close!) - Close player's inventory
 */
public class MrLibMessage {
    
    private final JavaPlugin plugin;
    private final MrLibActionBar actionBar;
    private final MrLibTitle title;
    
    private static final Pattern TAG_PATTERN = Pattern.compile("\\((!?)([^!)]+)(!?)\\)");
    
    public MrLibMessage(JavaPlugin plugin) {
        this.plugin = plugin;
        this.actionBar = new MrLibActionBar(plugin);
        this.title = new MrLibTitle(plugin);
    }
    
    /**
     * Send message with tag parsing
     * 
     * @param player Player
     * @param message Message with tags
     * 
     * Example:
     * "(!message!)Hello (!hover:Click me!)world (!actionbar!)ActionBar text (!title!)Title text"
     */
    public void send(Player player, String message) {
        if (message == null || message.isEmpty()) {
            return;
        }
        
        MessageParser parser = new MessageParser(message, player);
        parser.parse();
    }
    
    /**
     * Send to all players
     */
    public void sendToAll(String message) {
        for (Player player : plugin.getServer().getOnlinePlayers()) {
            send(player, message);
        }
    }
    
    /**
     * Send to players with permission
     */
    public void sendWithPermission(String message, String permission) {
        for (Player player : plugin.getServer().getOnlinePlayers()) {
            if (player.hasPermission(permission)) {
                send(player, message);
            }
        }
    }

    /**
     * Sends a smart message to a CommandSender (player or console).
     * Automatically loads from messages.yml, prepends prefix, and processes tags.
     */
    public void sendSmart(CommandSender sender, String pathOrMessage, String defaultPrefix) {
        if (sender == null) return;
        if (sender instanceof Player) {
            sendSmart((Player) sender, pathOrMessage, defaultPrefix);
        } else {
            List<String> lines = loadMessageLines(pathOrMessage);
            for (String line : lines) {
                if (line == null || line.isEmpty()) continue;

                if (line.toUpperCase().contains("(!SOUND!:")) {
                    line = line.replaceAll("(?i)\\(!SOUND!:[^)]+\\)", "");
                }

                if (line.toUpperCase().contains("(!ACTIONBAR!)")) {
                    line = line.replaceAll("(?i)\\(!ACTIONBAR!\\)", "");
                }

                if (line.toUpperCase().contains("(!TITLE!)") || line.toUpperCase().contains("(!SUBTITLE!)")) {
                    String titleText = "";
                    String subtitleText = "";
                    String upperLine = line.toUpperCase();
                    int titleIndex = upperLine.indexOf("(!TITLE!)");
                    int subtitleIndex = upperLine.indexOf("(!SUBTITLE!)");
                    if (titleIndex != -1 && subtitleIndex != -1) {
                        if (titleIndex < subtitleIndex) {
                            titleText = line.substring(titleIndex + 9, subtitleIndex).trim();
                            subtitleText = line.substring(subtitleIndex + 12).trim();
                        } else {
                            subtitleText = line.substring(subtitleIndex + 12, titleIndex).trim();
                            titleText = line.substring(titleIndex + 9).trim();
                        }
                    } else if (titleIndex != -1) {
                        titleText = line.substring(titleIndex + 9).trim();
                    } else if (subtitleIndex != -1) {
                        subtitleText = line.substring(subtitleIndex + 12).trim();
                    }
                    line = (titleText + " " + subtitleText).trim();
                }

                boolean noPrefix = false;
                if (line.toUpperCase().contains("(!NOPREFIX!)")) {
                    noPrefix = true;
                    line = line.replaceAll("(?i)\\(!NOPREFIX!\\)", "");
                }

                line = line.replaceAll("\\(![^!]*!\\)", "");

                if (!noPrefix && defaultPrefix != null && !defaultPrefix.isEmpty()) {
                    line = defaultPrefix + " " + line;
                }

                sender.sendMessage(MrLibColors.colorize(line));
            }
        }
    }

    /**
     * Sends a smart message to a player.
     * Automatically loads from messages.yml, prepends prefix, and processes tags.
     */
    public void sendSmart(Player player, String pathOrMessage, String defaultPrefix) {
        if (player == null || pathOrMessage == null || pathOrMessage.isEmpty()) {
            return;
        }

        List<String> lines = loadMessageLines(pathOrMessage);
        for (String line : lines) {
            if (line == null || line.isEmpty()) {
                continue;
            }

            Pattern soundPattern = Pattern.compile("(?i)\\(!SOUND!:([^)]+)\\)");
            Matcher soundMatcher = soundPattern.matcher(line);
            while (soundMatcher.find()) {
                String soundName = soundMatcher.group(1);
                playSound(player, soundName);
                line = line.replace(soundMatcher.group(0), "");
            }

            boolean isTitle = false;
            String titleText = null;
            String subtitleText = null;
            String upperLine = line.toUpperCase();
            if (upperLine.contains("(!TITLE!)") || upperLine.contains("(!SUBTITLE!)")) {
                isTitle = true;
                int titleIndex = upperLine.indexOf("(!TITLE!)");
                int subtitleIndex = upperLine.indexOf("(!SUBTITLE!)");

                if (titleIndex != -1 && subtitleIndex != -1) {
                    if (titleIndex < subtitleIndex) {
                        titleText = line.substring(titleIndex + 9, subtitleIndex).trim();
                        subtitleText = line.substring(subtitleIndex + 12).trim();
                    } else {
                        subtitleText = line.substring(subtitleIndex + 12, titleIndex).trim();
                        titleText = line.substring(titleIndex + 9).trim();
                    }
                } else if (titleIndex != -1) {
                    titleText = line.substring(titleIndex + 9).trim();
                } else if (subtitleIndex != -1) {
                    subtitleText = line.substring(subtitleIndex + 12).trim();
                }
            }

            if (isTitle) {
                title.show(player,
                        titleText != null ? MrLibColors.colorize(titleText, player) : "",
                        subtitleText != null ? MrLibColors.colorize(subtitleText, player) : "",
                        10, 70, 20
                );
                continue; 
            }

            
            boolean isActionBar = false;
            if (line.toUpperCase().contains("(!ACTIONBAR!)")) {
                isActionBar = true;
                line = line.replaceAll("(?i)\\(!ACTIONBAR!\\)", "");
            }

            if (isActionBar) {
                actionBar.show(player, MrLibColors.colorize(line.trim(), player));
                continue; 
            }

            
            boolean noPrefix = false;
            if (line.toUpperCase().contains("(!NOPREFIX!)")) {
                noPrefix = true;
                line = line.replaceAll("(?i)\\(!NOPREFIX!\\)", "");
            }

            
            if (!noPrefix && defaultPrefix != null && !defaultPrefix.isEmpty()) {
                if (line.contains("(!message!)")) {
                    line = line.replace("(!message!)", "(!message!)" + defaultPrefix + " ");
                } else {
                    line = "(!message!)" + defaultPrefix + " " + line;
                }
            }

            
            send(player, line);
        }
    }

    /**
     * Loads message lines from configuration. Supports string, lists, and scoped keys.
     * Falls back to pathOrMessage as a raw string if key not found.
     */
    public List<String> loadMessageLines(String pathOrMessage) {
        List<String> lines = new ArrayList<>();
        if (pathOrMessage == null || pathOrMessage.isEmpty()) {
            return lines;
        }

        java.io.File messagesFile = getMessagesFile();
        if (messagesFile.exists()) {
            org.bukkit.configuration.file.YamlConfiguration messages = org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(messagesFile);
            
            String lookupKey = translateKey(pathOrMessage);
            
            String pluginName = plugin.getName();
            String[] paths = {
                lookupKey,
                pluginName + "." + lookupKey,
                pluginName + ".Messages." + lookupKey,
                pluginName + ".messages." + lookupKey,
                pluginName.toLowerCase() + "." + lookupKey
            };
            
            Object val = null;
            for (String p : paths) {
                if (messages.contains(p)) {
                    val = messages.get(p);
                    break;
                }
            }
            
            if (val instanceof List) {
                for (Object o : (List<?>) val) {
                    if (o != null) lines.add(o.toString());
                }
            } else if (val != null) {
                lines.add(val.toString());
            }
        }
        
        if (lines.isEmpty()) {
            lines.add(pathOrMessage);
        }
        
        return lines;
    }

    /**
     * Helper to play sound safely with namespace or Bukkit sound enum.
     */
    private void playSound(Player player, String soundName) {
        if (soundName == null || soundName.isEmpty()) return;
        try {
            if (soundName.contains(":")) {
                player.playSound(player.getLocation(), soundName, 1.0f, 1.0f);
            } else {
                try {
                    org.bukkit.Sound sound = org.bukkit.Sound.valueOf(soundName.toUpperCase().replace(".", "_"));
                    player.playSound(player.getLocation(), sound, 1.0f, 1.0f);
                } catch (IllegalArgumentException ex) {
                    player.playSound(player.getLocation(), soundName, 1.0f, 1.0f);
                }
            }
        } catch (Exception e) {
            
        }
    }

    /**
     * Get message from config (backward compatibility)
     */
    public String getMessage(String path) {
        java.io.File messagesFile = getMessagesFile();
        
        if (messagesFile.exists()) {
            org.bukkit.configuration.file.YamlConfiguration messages = org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(messagesFile);
            
            String lookupKey = translateKey(path);
            
            
            String message = messages.getString(lookupKey);
            if (message != null) {
                return MrLibColors.colorize(message);
            }
            
            
            String pluginName = plugin.getName();
            String[] fallbacks = {
                pluginName + "." + lookupKey,
                pluginName + ".Messages." + lookupKey,
                pluginName + ".messages." + lookupKey,
                pluginName.toLowerCase() + "." + lookupKey
            };
            
            for (String fallback : fallbacks) {
                message = messages.getString(fallback);
                if (message != null) {
                    return MrLibColors.colorize(message);
                }
            }
        }
        return "&cMessage not found: " + path;
    }
    
    /**
     * Get message from config with default value (backward compatibility)
     */
    public String getMessage(String path, String defaultValue) {
        java.io.File messagesFile = getMessagesFile();
        if (messagesFile.exists()) {
            org.bukkit.configuration.file.YamlConfiguration messages = org.bukkit.configuration.file.YamlConfiguration.loadConfiguration(messagesFile);
            
            String lookupKey = translateKey(path);
            
            
            String message = messages.getString(lookupKey);
            if (message != null) {
                return MrLibColors.colorize(message);
            }
            
            
            String pluginName = plugin.getName();
            String[] fallbacks = {
                pluginName + "." + lookupKey,
                pluginName + ".Messages." + lookupKey,
                pluginName + ".messages." + lookupKey,
                pluginName.toLowerCase() + "." + lookupKey
            };
            
            for (String fallback : fallbacks) {
                message = messages.getString(fallback);
                if (message != null) {
                    return MrLibColors.colorize(message);
                }
            }
        }
        return MrLibColors.colorize(defaultValue);
    }

    private String translateKey(String path) {
        if (!"MrSellChests".equals(plugin.getName())) {
            return path;
        }
        if (path == null) return null;
        switch (path) {
            case "no_permission":
            case "no-permission":
                return "General.Missing-Permission";
            case "no_permission_place":
            case "no-permission-place":
                return "General.Missing-Permission-Place";
            case "command_usage":
                return "General.Command-Usage";
            case "unknown_subcommand":
                return "General.Unknown-Subcommand";
            case "reload_success":
                return "General.Reload-Success";
            case "invalid_page_number":
                return "General.Invalid-Page-Number";
            
            case "chest_created":
                return "Chest.Created";
            case "chest_limit_reached":
                return "Chest.Limit-Reached";
            case "not_owner":
            case "invite_no_chest_owner":
            case "edit_no_chest_owner":
                return "Chest.Not-Owner";
            case "chest_destroyed":
                return "Chest.Destroyed";
            case "chest_same_chunk":
                return "Chest.Same-Chunk";
            case "hologram_disabled":
                return "Chest.Hologram-Disabled";
            case "hologram_failed":
                return "Chest.Hologram-Failed";
            case "chest_already_fully_charged":
                return "Chest.Already-Fully-Charged";
            case "chest_charge_not_enough_money":
                return "Chest.Charge-Not-Enough-Money";
            case "chest_charged_success":
                return "Chest.Charged-Success";
            case "chest_type_no_charging":
                return "Chest.Type-No-Charging";
            case "sell_inventory_not_available":
                return "Chest.Sell-Inventory-Not-Available";
            case "container_not_available":
                return "Chest.Container-Not-Available";
            case "banned_item_inventory":
                return "Chest.Banned-Item-Inventory";
            case "banned_item_added":
                return "Chest.Banned-Item-Added";
            case "banned_item_removed":
                return "Chest.Banned-Item-Removed";
            case "banned_item_not_found":
                return "Chest.Banned-Item-Not-Found";
            case "banned_item_usage":
                return "Chest.Banned-Item-Usage";
            case "banned_item_no_item":
                return "Chest.Banned-Item-No-Item";
            case "banned_item_invalid_category":
                return "Chest.Banned-Item-Invalid-Category";
            case "banned_item_invalid_action":
                return "Chest.Banned-Item-Invalid-Action";
            case "banned_item_already_banned":
                return "Chest.Banned-Item-Already-Banned";
            case "banned_item_not_banned":
                return "Chest.Banned-Item-Not-Banned";
            case "banned_item_add_success":
                return "Chest.Banned-Item-Add-Success";
            case "banned_item_remove_success":
                return "Chest.Banned-Item-Remove-Success";
            case "banned_item_save_error":
                return "Chest.Banned-Item-Save-Error";
                
            case "chest_link_start":
                return "Linking.Start";
            case "chest_link_success":
                return "Linking.Success";
            case "chest_link_cancelled":
                return "Linking.Cancelled";
            case "chest_unlink_all":
                return "Linking.Unlink-All";
            case "chest_link_max":
                return "Linking.Max";
            case "chest_link_max_disabled":
                return "Linking.Max-Disabled";
            case "chest_link_invalid":
                return "Linking.Invalid";
            case "chest_link_sell_chest":
                return "Linking.Sell-Chest";
                
            case "pickup_link_start":
                return "Pickup.Start";
            case "pickup_link_success":
                return "Pickup.Success";
            case "pickup_link_cancelled":
                return "Pickup.Cancelled";
            case "pickup_unlink_success":
                return "Pickup.Unlink-Success";
                
            case "state_linked":
                return "State.Linked";
            case "state_unlinked":
                return "State.Unlinked";
            case "state_enabled":
                return "State.Enabled";
            case "state_disabled":
                return "State.Disabled";
                
            case "linked_chests_full":
                return "Trasher.Chests-Full";
            case "trasher_mode_changed":
                return "Trasher.Mode-Changed";
            case "trasher_mode_KEEP":
                return "Trasher.Mode-KEEP";
            case "trasher_mode_TRANSFER":
                return "Trasher.Mode-TRANSFER";
            case "trasher_mode_REMOVE":
                return "Trasher.Mode-REMOVE";
                
            case "boost_set":
                return "Booster.Boost-Set";
            case "boost_received":
                return "Booster.Boost-Received";
            case "booster_activated":
                return "Booster.Booster-Activated";
            case "booster_already_active":
                return "Booster.Booster-Already-Active";
            case "boost_time_left":
                return "Booster.Boost-Time-Left";
            case "booster_voucher_name":
                return "Booster.Voucher-Name";
            case "booster_give_usage":
                return "Booster.Give-Usage";
            case "booster_give_success":
                return "Booster.Give-Success";
            case "booster_not_found":
                return "Booster.Not-Found";
            case "booster_item_not_defined":
                return "Booster.Item-Not-Defined";
            case "boosters_yml_not_found":
                return "Booster.Yml-Not-Found";
            case "booster_invalid_amount":
                return "Booster.Invalid-Amount";
                
            case "sell_success":
                return "Sell.Success";
            case "sell_chest_interval_message":
                return "Sell.Interval-Message";
            case "sell_chest_full":
                return "Sell.Chest-Full";
            case "invalid_item":
                return "Sell.Invalid-Item";
            case "not_enough_money":
                return "Sell.Not-Enough-Money";
                
            case "give_usage":
                return "Command.Give-Usage";
            case "give_invalid_amount":
                return "Command.Give-Invalid-Amount";
            case "give_player_not_found":
                return "Command.Give-Player-Not-Found";
            case "give_chest_type_not_found":
                return "Command.Give-Chest-Type-Not-Found";
            case "give_success":
                return "Command.Give-Success";
            case "boost_usage":
                return "Command.Boost-Usage";
            case "boost_invalid":
                return "Command.Boost-Invalid";
            case "help_players_only":
                return "Command.Help-Players-Only";
                
            case "invite_already_in_process":
                return "Invite.Already-In-Process";
            case "invite_max_players_reached":
                return "Invite.Max-Players-Reached";
            case "invite_process_start":
                return "Invite.Process-Start";
            case "invite_enter_player_name":
                return "Invite.Enter-Player-Name";
            case "invite_player_must_be_online":
                return "Invite.Player-Must-Be-Online";
            case "invite_type_cancel":
                return "Invite.Type-Cancel";
            case "invite_failed_start":
                return "Invite.Failed-Start";
            case "invite_cancelled_missing_data":
                return "Invite.Cancelled-Missing-Data";
            case "invite_cancelled":
                return "Invite.Cancelled";
            case "invite_player_not_online":
                return "Invite.Player-Not-Online";
            case "invite_cannot_invite_self":
                return "Invite.Cannot-Invite-Self";
            case "invite_player_found":
                return "Invite.Player-Found";
            case "invite_enter_percentage":
                return "Invite.Enter-Percentage";
            case "invite_percentage_example":
                return "Invite.Percentage-Example";
            case "invite_percentage_invalid":
                return "Invite.Percentage-Invalid";
            case "invite_player_offline":
                return "Invite.Player-Offline";
            case "invite_no_longer_owner":
                return "Invite.No-Longer-Owner";
            case "invite_player_already_invited":
                return "Invite.Player-Already-Invited";
            case "invite_success_owner":
                return "Invite.Success-Owner";
            case "invite_success_target":
                return "Invite.Success-Target";
            case "invite_failed":
                return "Invite.Failed";
            case "invite_uninvite_success_online":
                return "Invite.Uninvite-Success-Online";
            case "invite_uninvite_success_offline":
                return "Invite.Uninvite-Success-Offline";
            case "invite_uninvite_target":
                return "Invite.Uninvite-Target";
            case "invite_uninvite_failed":
                return "Invite.Uninvite-Failed";
            case "invite_menu_open_failed":
                return "Invite.Menu-Open-Failed";
                
            case "edit_already_in_process":
                return "Edit.Already-In-Process";
            case "edit_process_start":
                return "Edit.Process-Start";
            case "edit_current_player":
                return "Edit.Current-Player";
            case "edit_current_percentage":
                return "Edit.Current-Percentage";
            case "edit_enter_new_percentage":
                return "Edit.Enter-New-Percentage";
            case "edit_type_cancel":
                return "Edit.Type-Cancel";
            case "edit_failed_start":
                return "Edit.Failed-Start";
            case "edit_cancelled_missing_data":
                return "Edit.Cancelled-Missing-Data";
            case "edit_cancelled":
                return "Edit.Cancelled";
            case "edit_percentage_invalid":
                return "Edit.Percentage-Invalid";
            case "edit_no_longer_owner":
                return "Edit.No-Longer-Owner";
            case "edit_player_no_longer_invited":
                return "Edit.Player-No-Longer-Invited";
            case "edit_success":
                return "Edit.Success";
            case "edit_notification":
                return "Edit.Notification";
            case "edit_failed":
                return "Edit.Failed";
        }
        return path;
    }
    
    /**
     * Message parser
     */
    private class MessageParser {
        private final String input;
        private final Player player;
        private String currentMode = "message";
        private List<MessagePart> parts = new ArrayList<>();
        private String pendingHover = null;
        private String pendingClick = null;
        private String pendingSound = null;
        private boolean shouldCloseInventory = false;
        
        public MessageParser(String input, Player player) {
            this.input = input;
            this.player = player;
        }
        
        public void parse() {
            Matcher matcher = TAG_PATTERN.matcher(input);
            int lastEnd = 0;
            
            while (matcher.find()) {
                
                if (matcher.start() > lastEnd) {
                    String text = input.substring(lastEnd, matcher.start());
                    if (!text.isEmpty()) {
                        MessagePart part = new MessagePart(currentMode, text, null);
                        applyPendingEffects(part);
                        parts.add(part);
                    }
                }
                
                
                String leftExclamation = matcher.group(1);
                String tag = matcher.group(2);
                String rightExclamation = matcher.group(3);
                
                
                parseTag(tag);
                
                lastEnd = matcher.end();
            }
            
            
            if (lastEnd < input.length()) {
                String text = input.substring(lastEnd);
                if (!text.isEmpty()) {
                    MessagePart part = new MessagePart(currentMode, text, null);
                    applyPendingEffects(part);
                    parts.add(part);
                }
            }
            
            
            execute();
        }
        
        private void parseTag(String tag) {
            String normalizedTag = tag.toLowerCase(java.util.Locale.ROOT);
            if (normalizedTag.startsWith("hover:")) {
                pendingHover = tag.substring(6);
            } else if (normalizedTag.startsWith("click:")) {
                pendingClick = tag.substring(6);
            } else if (normalizedTag.startsWith("sound:")) {
                pendingSound = tag.substring(6);
            } else if (tag.equalsIgnoreCase("close")) {
                shouldCloseInventory = true;
            } else {
                currentMode = tag.toLowerCase();
            }
        }
        
        private void applyPendingEffects(MessagePart part) {
            if (pendingHover != null) {
                part.hoverText = pendingHover;
                pendingHover = null;
            }
            if (pendingClick != null) {
                part.clickCommand = pendingClick;
                pendingClick = null;
            }
            if (pendingSound != null) {
                part.soundName = pendingSound;
                pendingSound = null;
            }
        }
        
        private void execute() {
            List<TextComponent> chatComponents = new ArrayList<>();
            String titleText = null;
            String subtitleText = null;
            String actionBarText = null;

            for (MessagePart part : parts) {
                String colored = MrLibColors.colorize(part.text, player);

                switch (part.mode) {
                    case "message":
                        
                        BaseComponent[] components = TextComponent.fromLegacyText(colored);
                        
                        
                        if (part.hoverText != null || part.clickCommand != null) {
                            for (BaseComponent comp : components) {
                                if (part.hoverText != null) {
                                    String coloredHover = MrLibColors.colorize(part.hoverText, player);
                                    BaseComponent[] hoverComponents = TextComponent.fromLegacyText(coloredHover);
                                    comp.setHoverEvent(new HoverEvent(
                                        HoverEvent.Action.SHOW_TEXT,
                                        hoverComponents
                                    ));
                                }
                                
                                if (part.clickCommand != null) {
                                    boolean url = part.clickCommand.regionMatches(true, 0, "URL:", 0, 4)
                                            || part.clickCommand.regionMatches(true, 0, "HTTP", 0, 4);
                                    String target = part.clickCommand.regionMatches(true, 0, "URL:", 0, 4)
                                            ? part.clickCommand.substring(4) : part.clickCommand;
                                    comp.setClickEvent(new ClickEvent(
                                        url ? ClickEvent.Action.OPEN_URL : ClickEvent.Action.RUN_COMMAND,
                                        target
                                    ));
                                }
                            }
                        }
                        
                        
                        for (BaseComponent comp : components) {
                            if (comp instanceof TextComponent) {
                                chatComponents.add((TextComponent) comp);
                            }
                        }
                        break;

                    case "title":
                        titleText = colored;
                        break;

                    case "subtitle":
                        subtitleText = colored;
                        break;

                    case "actionbar":
                        actionBarText = colored;
                        break;
                }
            }

            
            if (!chatComponents.isEmpty()) {
                
                BaseComponent[] messageComponents = new BaseComponent[chatComponents.size()];
                for (int i = 0; i < chatComponents.size(); i++) {
                    messageComponents[i] = chatComponents.get(i);
                }
                player.spigot().sendMessage(messageComponents);
            }
            
            
            if (titleText != null || subtitleText != null) {
                title.show(player, 
                    titleText != null ? titleText : "",
                    subtitleText != null ? subtitleText : "",
                    10, 70, 20
                );
            }
            
            
            if (actionBarText != null) {
                actionBar.show(player, actionBarText);
            }

            
            for (MessagePart part : parts) {
                if (part.soundName != null && !part.soundName.isEmpty()) {
                    try {
                        org.bukkit.Sound sound = org.bukkit.Sound.valueOf(part.soundName.toUpperCase());
                        player.playSound(player.getLocation(), sound, 1.0f, 1.0f);
                    } catch (IllegalArgumentException e) {
                        
                    }
                }
            }
            
            
            if (shouldCloseInventory) {
                player.closeInventory();
            }
        }
    }
    
    private java.io.File getMessagesFile() {
        java.io.File messagesFile = new java.io.File(plugin.getDataFolder(), "messages.yml");
        if (!messagesFile.exists()) {
            String language = plugin.getConfig().getString("MrSellChests.Engine.Language");
            if (language == null) language = plugin.getConfig().getString("Engine.Language");
            if (language == null) language = plugin.getConfig().getString("Language", "english");
            
            java.io.File langMessages = new java.io.File(plugin.getDataFolder(), "languages/" + language + "/messages.yml");
            if (langMessages.exists()) {
                return langMessages;
            }
            java.io.File englishMessages = new java.io.File(plugin.getDataFolder(), "languages/english/messages.yml");
            if (englishMessages.exists()) {
                return englishMessages;
            }
        }
        return messagesFile;
    }
    
    /**
     * Message part
     */
    private static class MessagePart {
        String mode;
        String text;
        String hoverText;
        String clickCommand;
        String soundName;

        MessagePart(String mode, String text, String hover) {
            this.mode = mode;
            this.text = text;
            this.hoverText = hover;
        }
    }
}

865 linesGNU GENERAL PUBLIC LICENSE · Version 3, 29 June 2007 · UTF-8 · Read only