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/config/MrLibConfigConverter.java
JAVA · Read-only source
package eu.mrneznamy.mrultimatelibrary.config;
import eu.mrneznamy.mrultimatelibrary.utils.MrLibConsoleSayer;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.*;
/**
* Converts old configuration files to new format with comments
* Handles migration of existing user configs to centralized system
*/
public class MrLibConfigConverter {
private final JavaPlugin plugin;
private final Map<String, List<ConversionRule>> conversionRules = new HashMap<>();
private final Map<String, List<String>> fileComments = new HashMap<>();
public MrLibConfigConverter(JavaPlugin plugin) {
this.plugin = plugin;
setupConversionRules();
setupComments();
}
/**
* Check if config should be skipped from conversion
* @param configName Name of config file
* @return true if should skip conversion
*/
private boolean shouldSkipConversion(String configName) {
String pluginName = plugin.getName();
if (pluginName.equals("MrUltimateShop")) {
if (configName.equals("menu.yml") ||
configName.equals("tracker.yml") ||
configName.equals("sell-gui.yml") ||
configName.equals("sell-all-gui.yml") ||
configName.equals("buy-gui.yml") ||
configName.startsWith("Shops/")) {
return true;
}
}
if (pluginName.equals("MrUltimateJobs")) {
if (configName.equals("events.yml") ||
configName.equals("boosters.yml") ||
configName.equals("tournaments.yml") ||
configName.equals("data.yml") ||
configName.startsWith("Jobs/") ||
configName.startsWith("Menus/")) {
return true;
}
}
return false;
}
/**
* Converts old config to new format
* @param configName Name of config file (e.g. "config.yml")
* @return true if conversion was successful
*/
public boolean convertConfig(String configName) {
if (shouldSkipConversion(configName)) {
return false;
}
File oldFile = new File(plugin.getDataFolder(), configName);
if (!oldFile.exists()) {
return false;
}
try {
File backupFolder = new File(plugin.getDataFolder(), "backupFiles");
if (!backupFolder.exists()) {
backupFolder.mkdirs();
}
String timestamp = new java.text.SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(new java.util.Date());
File backupFile = new File(backupFolder, configName + ".old-backup." + timestamp);
Files.copy(oldFile.toPath(), backupFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
MrLibConsoleSayer.MrSay_Info("[" + plugin.getName() + "] Backed up old " + configName + " to backupFiles/" + backupFile.getName());
YamlConfiguration oldConfig = YamlConfiguration.loadConfiguration(oldFile);
MrLibYamlConfiguration newConfig = new MrLibYamlConfiguration();
List<ConversionRule> rules = conversionRules.get(configName);
if (rules != null) {
for (ConversionRule rule : rules) {
rule.apply(oldConfig, newConfig);
}
} else {
for (String key : oldConfig.getKeys(true)) {
if (!oldConfig.isConfigurationSection(key)) {
newConfig.set(key, oldConfig.get(key));
}
}
}
List<String> comments = fileComments.get(configName);
if (comments != null) {
for (String comment : comments) {
String[] parts = comment.split("\\|", 2);
if (parts.length == 2) {
newConfig.addComment(parts[0], parts[1]);
}
}
}
newConfig.save(oldFile);
MrLibConsoleSayer.MrSay_Success("[" + plugin.getName() + "] Converted " + configName + " to new format");
return true;
} catch (Exception e) {
MrLibConsoleSayer.MrSay_Error("[" + plugin.getName() + "] Failed to convert " + configName + ": " + e.getMessage());
return false;
}
}
/**
* Checks if config needs conversion
*/
public boolean needsConversion(String configName) {
File configFile = new File(plugin.getDataFolder(), configName);
if (!configFile.exists()) {
return false;
}
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
if (config.contains("MrUltimateLibrary-Configs-Version")) {
return false;
}
String versionKey = configName.replace(".yml", "") + "-version";
return !config.contains(versionKey);
}
/**
* Setup conversion rules for each plugin
*/
private void setupConversionRules() {
if (plugin.getName().equals("MrUltimateShop")) {
setupMrUltimateShopRules();
} else if (plugin.getName().equals("MrUltimateHoppers")) {
setupMrUltimateHoppersRules();
} else if (plugin.getName().equals("MrUltimateJobs")) {
setupMrUltimateJobsRules();
} else if (plugin.getName().equals("MrVoteTrain")) {
setupMrVoteTrainRules();
} else if (plugin.getName().equals("MrSellChests")) {
setupMrSellChestsRules();
}
}
/**
* Setup comments for each plugin
*/
private void setupComments() {
if (plugin.getName().equals("MrUltimateShop")) {
setupMrUltimateShopComments();
} else if (plugin.getName().equals("MrSellChests")) {
setupMrSellChestsComments();
}
}
private void setupMrUltimateShopRules() {
List<ConversionRule> rules = new ArrayList<>();
rules.add((oldConfig, newConfig) -> {
newConfig.set("config-version", 1);
});
rules.add((oldConfig, newConfig) -> {
for (String key : oldConfig.getKeys(true)) {
if (!oldConfig.isConfigurationSection(key)) {
Object value = oldConfig.get(key);
if (key.startsWith("MrUltimateShop.")) {
newConfig.set(key, value);
}
else if (key.startsWith("Database.") || key.startsWith("economy.") ||
key.startsWith("Logging.") || key.startsWith("World-Settings.") ||
key.startsWith("Features.") || key.startsWith("shop.") ||
key.startsWith("messages.") || key.startsWith("ChestShops.")) {
newConfig.set("MrUltimateShop." + key, value);
}
else {
newConfig.set(key, value);
}
}
}
});
rules.add((oldConfig, newConfig) -> {
if (!newConfig.contains("MrUltimateShop.Database")) {
newConfig.set("MrUltimateShop.Database.Type", "yml");
newConfig.set("MrUltimateShop.Database.SQLite.FileName", "ultimateshop.db");
newConfig.set("MrUltimateShop.Database.MySQL.Host", "localhost");
newConfig.set("MrUltimateShop.Database.MySQL.Port", 3306);
newConfig.set("MrUltimateShop.Database.MySQL.Database", "ultimateshop");
newConfig.set("MrUltimateShop.Database.MySQL.Username", "root");
newConfig.set("MrUltimateShop.Database.MySQL.Password", "");
}
});
rules.add((oldConfig, newConfig) -> {
if (newConfig.contains("MrUltimateShop.economy.use-vault")) {
boolean useVault = newConfig.getBoolean("MrUltimateShop.economy.use-vault", true);
String symbol = newConfig.getString("MrUltimateShop.economy.currency-symbol", "$");
String format = newConfig.getString("MrUltimateShop.economy.number-format", "#,##0.00");
newConfig.set("MrUltimateShop.economy.use-vault", null);
newConfig.set("MrUltimateShop.economy.currency-symbol", null);
newConfig.set("MrUltimateShop.economy.number-format", null);
newConfig.set("MrUltimateShop.Economy.Vault.Enabled", useVault);
newConfig.set("MrUltimateShop.Economy.Vault.Symbol", symbol);
newConfig.set("MrUltimateShop.Economy.Vault.Number-Format", format);
newConfig.set("MrUltimateShop.Economy.MrVoteTrain.Enabled", false);
newConfig.set("MrUltimateShop.Economy.MrVoteTrain.Symbol", " VB");
newConfig.set("MrUltimateShop.Economy.MrVoteTrain.Number-Format", "#,##0");
}
});
conversionRules.put("config.yml", rules);
List<ConversionRule> messagesRules = new ArrayList<>();
messagesRules.add((oldConfig, newConfig) -> {
newConfig.set("messages-version", 1);
});
messagesRules.add((oldConfig, newConfig) -> {
for (String key : oldConfig.getKeys(true)) {
if (!oldConfig.isConfigurationSection(key)) {
Object value = oldConfig.get(key);
if (key.startsWith("MrUltimateShop.")) {
newConfig.set(key, value);
}
else if (key.startsWith("general.") || key.startsWith("shop.") ||
key.startsWith("sell.") || key.startsWith("sell-gui.") ||
key.startsWith("buysell.") || key.startsWith("errors.") ||
key.startsWith("commands.") || key.startsWith("Chest-Shop.")) {
String messageKey = key.substring(key.indexOf(".") + 1);
String messageText = value.toString();
if (!messageText.contains("(!message!)") && !messageText.contains("(!NOPREFIX!)")) {
messageText = "(!message!)" + messageText;
}
newConfig.set("MrUltimateShop." + messageKey.replace(".", "-"), messageText);
}
else {
newConfig.set(key, value);
}
}
}
});
conversionRules.put("messages.yml", messagesRules);
}
private void setupMrUltimateShopComments() {
}
private void setupMrUltimateHoppersRules() {
}
private void setupMrUltimateJobsRules() {
List<ConversionRule> messageRules = new ArrayList<>();
messageRules.add((oldConfig, newConfig) -> {
newConfig.set("messages-version", 1);
});
messageRules.add((oldConfig, newConfig) -> {
MrLibConsoleSayer.MrSay_Info("Converting messages.yml for MrUltimateJobs...");
for (String key : oldConfig.getKeys(true)) {
if (oldConfig.isString(key)) {
String messageText = oldConfig.getString(key);
if (messageText != null && !messageText.trim().isEmpty()) {
messageText = messageText.replace("{prefix}", "");
boolean hasNoPrefix = messageText.contains("(!NOPREFIX!)");
boolean hasMessageTag = messageText.contains("(!message!)");
boolean hasTitleTag = messageText.contains("(!title!)");
boolean hasActionbarTag = messageText.contains("(!actionbar!)");
boolean hasSubtitleTag = messageText.contains("(!subtitle!)");
boolean isActionbarKey = key.toLowerCase().contains("actionbar");
boolean isGuiKey = key.toLowerCase().contains("name") ||
key.toLowerCase().contains("active") ||
key.toLowerCase().contains("inactive") ||
key.toLowerCase().contains("display-name") ||
key.toLowerCase().contains("material") ||
key.toLowerCase().contains("custom-model-data") ||
key.toLowerCase().contains("glowing") ||
key.toLowerCase().contains("description") ||
key.toLowerCase().contains("lore");
if (hasTitleTag || hasActionbarTag || hasSubtitleTag || isActionbarKey || isGuiKey) {
messageText = messageText.replaceAll("\\(![^!]*!\\)", "");
} else if (!hasMessageTag && !hasNoPrefix && !hasTitleTag && !hasActionbarTag && !hasSubtitleTag) {
messageText = "(!message!)" + messageText;
}
newConfig.set("MrUltimateJobs." + key, messageText);
}
}
}
});
messageRules.add((oldConfig, newConfig) -> {
List<String> messageComments = new ArrayList<>();
messageComments.add("_HEADER_|# MrUltimateJobs Messages Configuration");
messageComments.add("_HEADER_|# Use & for color codes");
messageComments.add("_HEADER_|# Available placeholders: [PlayerName], [Level], [XP], [Money], [Job], [EventName], [TournamentName]");
messageComments.add("_HEADER_|# ========================================");
messageComments.add("_HEADER_|# Available tags:");
messageComments.add("_HEADER_|# (!message!) (!title!) (!subtitle!) (!actionbar!)");
messageComments.add("_HEADER_|# (!sound:SOUND!) (!close!) (!NOPREFIX!)");
messageComments.add("_HEADER_|# ========================================");
messageComments.add("messages-version|# Do not change this! Used for automatic config updates");
newConfig.setComments("", messageComments);
});
conversionRules.put("messages.yml", messageRules);
}
private void setupMrVoteTrainRules() {
}
private void setupMrSellChestsRules() {
List<ConversionRule> rules = new ArrayList<>();
rules.add((oldConfig, newConfig) -> {
newConfig.set("MrUltimateLibrary-Configs-Version", "1.0.0");
});
rules.add((oldConfig, newConfig) -> {
for (String key : oldConfig.getKeys(true)) {
if (!oldConfig.isConfigurationSection(key)) {
Object value = oldConfig.get(key);
if (key.equalsIgnoreCase("config-version")) continue;
if (key.startsWith("MrSellChests.")) {
newConfig.set(key, value);
} else if (key.startsWith("SellChests.")) {
newConfig.set("MrSellChests." + key, value);
} else if (key.startsWith("Database.") || key.startsWith("Holograms.") ||
key.startsWith("Economy.") || key.startsWith("SettingsMenu.") ||
key.startsWith("OfflineSell") || key.startsWith("SellPrices.") ||
key.startsWith("Sell-Message.")) {
newConfig.set("MrSellChests." + key, value);
} else {
newConfig.set(key, value);
}
}
}
});
conversionRules.put("config.yml", rules);
List<ConversionRule> msgRules = new ArrayList<>();
msgRules.add((oldConfig, newConfig) -> {
newConfig.set("MrUltimateLibrary-Configs-Version", "1.0.0");
for (String key : oldConfig.getKeys(true)) {
if (!oldConfig.isConfigurationSection(key)) {
newConfig.set(key, oldConfig.get(key));
}
}
});
conversionRules.put("messages.yml", msgRules);
}
private void setupMrSellChestsComments() {
List<String> header = new ArrayList<>();
header.add("# ========================================");
header.add("# MrSellChests Configuration");
header.add("# ");
header.add("# All configuration options are described");
header.add("# with comments to help you understand");
header.add("# what each setting does.");
header.add("# ========================================");
MrLibYamlConfiguration config = new MrLibYamlConfiguration();
config.setHeaderComments(header);
config.addComment("MrSellChests.Database", "# Database configuration - stores sell chest data\n# Types: yml (default), sqlite, mysql");
config.addComment("MrSellChests.Database.Type", "# Storage type\n# yml - stores data in data.yml and boosters.yml files (default, no setup required)\n# sqlite - stores data in a local database file (good for medium servers)\n# mysql - stores data in a MySQL database (best for large servers or networks)");
config.addComment("MrSellChests.Database.SQLite", "# SQLite settings (only used if Type: sqlite)");
config.addComment("MrSellChests.Database.SQLite.FileName", "# Database file name");
config.addComment("MrSellChests.Database.MySQL", "# MySQL settings (only used if Type: mysql)");
config.addComment("MrSellChests.Database.MySQL.Host", "# MySQL server host");
config.addComment("MrSellChests.Database.MySQL.Port", "# MySQL server port (default: 3306)");
config.addComment("MrSellChests.Database.MySQL.Database", "# MySQL database name");
config.addComment("MrSellChests.Database.MySQL.Username", "# MySQL username");
config.addComment("MrSellChests.Database.MySQL.Password", "# MySQL password");
config.addComment("MrSellChests.OfflineSell", "# Offline selling\n# If true, sell chests continue selling while the player is offline\n# If false, sell chests only work when the player is online");
config.addComment("MrSellChests.Holograms", "# Hologram settings - displays information above sell chests");
config.addComment("MrSellChests.Holograms.Enabled", "# Enable or disable holograms");
config.addComment("MrSellChests.Holograms.Provider", "# Hologram provider\n# MrUltimateLibrary - native holograms, no plugin required (recommended)");
config.addComment("MrSellChests.Holograms.UpdateInterval", "# How often to update hologram text (in ticks, 20 ticks = 1 second)\n# Lower values = more frequent updates but more server resources");
config.addComment("MrSellChests.SellPrices", "# Sell prices configuration");
config.addComment("MrSellChests.SellPrices.Provider", "# Price provider\n# FILE - uses sell-prices.yml file (included with plugin)\n# SHOPGUI+ - uses prices from ShopGUIPlus plugin\n# EconomyShopGUI - uses prices from EconomyShopGUI plugin\n# MrUltimateShop - uses prices from MrUltimateShop plugin\n# ExcellentShop - uses prices from ExcellentShop plugin");
config.addComment("MrSellChests.Economy", "# Economy settings");
config.addComment("MrSellChests.Economy.Enabled", "# Enable economy integration");
config.addComment("MrSellChests.Economy.Provider", "# Economy provider (currently only Vault is supported)");
config.addComment("MrSellChests.Sell-Message", "# Sell message settings\n# Sends a message to players about their earnings");
config.addComment("MrSellChests.Sell-Message.Enabled", "# Enable periodic sell messages");
config.addComment("MrSellChests.Sell-Message.Interval", "# How often to send messages (in minutes)\n# Example: 1 = every 1 minute, 5 = every 5 minutes");
config.addComment("MrSellChests.Sell-Message.Message", "# Message format (prefix is not used for this message)\n# Placeholders:\n# [MoneyEarned] - amount of money earned\n# [Interval] - time interval in minutes");
config.addComment("MrSellChests.SellChests", "# Sell chest types configuration\n# You can create multiple types of sell chests with different settings\n# Players can have custom chest types here");
config.addComment("MrSellChests.SettingsMenu", "# Menu title");
config.addComment("MrSellChests.SettingsMenu.titleforsellinv", "# Sell inventory title");
config.addComment("MrSellChests.SettingsMenu.size", "# Menu size (must be multiple of 9)");
config.addComment("MrSellChests.SettingsMenu.Filters", "# Decorative items (filters)");
config.addComment("MrSellChests.SettingsMenu.Filters.1", "# First decoration pattern");
config.addComment("MrSellChests.SettingsMenu.Filters.1.slot", "# Slots where this item appears (comma-separated)");
config.addComment("MrSellChests.SettingsMenu.Filters.2", "# Second decoration pattern");
config.addComment("MrSellChests.SettingsMenu.items", "# Functional items in the menu");
config.addComment("MrSellChests.SettingsMenu.items.sell_inventory", "# Sell inventory button");
config.addComment("MrSellChests.SettingsMenu.items.statistics", "# Statistics display");
config.addComment("MrSellChests.SettingsMenu.items.toggle_hologram", "# Toggle hologram button");
config.addComment("MrSellChests.SettingsMenu.items.trasher", "# Item trasher mode button\n# Controls what happens to non-sellable items");
config.addComment("MrSellChests.SettingsMenu.items.trasher.Items.REMOVE", "# Remove mode - deletes non-sellable items");
config.addComment("MrSellChests.SettingsMenu.items.trasher.Items.KEEP", "# Keep mode - keeps non-sellable items in inventory");
config.addComment("MrSellChests.SettingsMenu.items.trasher.Items.TRANSFER", "# Transfer mode - moves non-sellable items to linked chests");
config.addComment("MrSellChests.SettingsMenu.items.trasher.Items.TRANSFER.Link_Item", "# Link chest button (only visible in TRANSFER mode)");
config.addComment("MrSellChests.SettingsMenu.items.chunk_collector", "# Chunk collector toggle\n# Automatically collects items from the chunk");
config.addComment("MrSellChests.SettingsMenu.items.invite_players", "# Invite Players button (only visible to owners)");
config.addComment("MrSellChests.SettingsMenu.items.charge_chest", "# Charge chest button (only for CHARGING type)");
for (Map.Entry<String, String> entry : config.getComments().entrySet()) {
addFileComment("config.yml", entry.getKey() + "|" + entry.getValue());
}
for (String h : header) {
addFileComment("config.yml", "_HEADER_|" + h);
}
}
private void addFileComment(String file, String comment) {
fileComments.computeIfAbsent(file, k -> new ArrayList<>()).add(comment);
}
/**
* Conversion rule interface
*/
@FunctionalInterface
public interface ConversionRule {
void apply(YamlConfiguration oldConfig, MrLibYamlConfiguration newConfig);
}
}
528 linesGNU GENERAL PUBLIC LICENSE · Version 3, 29 June 2007 · UTF-8 · Read only