From 89a5ae404b2e99506d619b6773a305ede13b9bd3 Mon Sep 17 00:00:00 2001 From: Archy-X Date: Thu, 16 May 2024 17:06:57 -0700 Subject: [PATCH] Only update menu files with specifically added keys --- .../bukkit/menus/MenuFileManager.java | 45 ++- .../bukkit/menus/MenuFileUpdates.java | 52 +++ .../resources/menus/level_progression.yml | 303 ++++++++++-------- bukkit/src/main/resources/menus/skills.yml | 173 ++++++---- 4 files changed, 375 insertions(+), 198 deletions(-) create mode 100644 bukkit/src/main/java/dev/aurelium/auraskills/bukkit/menus/MenuFileUpdates.java diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/menus/MenuFileManager.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/menus/MenuFileManager.java index e37fa9c86..8a3ac8658 100644 --- a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/menus/MenuFileManager.java +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/menus/MenuFileManager.java @@ -11,6 +11,8 @@ import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; public class MenuFileManager { @@ -50,7 +52,7 @@ public void updateMenus() { ConfigurationNode embeddedConfig = FileUtil.loadEmbeddedYamlFile("menus/" + menuName + ".yml", plugin); ConfigurationNode userConfig = FileUtil.loadYamlFile(userFile); - updateAndSave(embeddedConfig, userConfig, userFile); + updateAndSave(menuName, embeddedConfig, userConfig, userFile); } catch (IOException e) { plugin.logger().warn("Error updating menu file " + userFile.getName()); e.printStackTrace(); @@ -58,16 +60,35 @@ public void updateMenus() { } } - private void updateAndSave(ConfigurationNode embedded, ConfigurationNode user, File userFile) throws SerializationException { - int changed = 0; - changed += updateConfigSection("items", embedded, user); - changed += updateConfigSection("templates", embedded, user); - changed += updateConfigSection("components", embedded, user); - changed += updateStringSection("formats", embedded, user); + private void updateAndSave(String menuName, ConfigurationNode embedded, ConfigurationNode user, File userFile) throws SerializationException { + // Files that don't have updating enabled yet, since they haven't had changes + if (embedded.node("file_version").virtual()) return; + + int embVersion = embedded.node("file_version").getInt(); + int userVersion = user.node("file_version").getInt(0); - if (changed <= 0) { + // User file is already up-to-date + if (userVersion >= embVersion) { return; } + + List updates = MenuFileUpdates.getUpdates(menuName, userVersion, embVersion); + if (updates.isEmpty()) return; + + int changed = 0; + for (MenuFileUpdates update : updates) { + List addedItems = update.getAddedKeys().getOrDefault("items", new ArrayList<>()); + changed += updateConfigSection("items", embedded, user, addedItems); + List addedTemplates = update.getAddedKeys().getOrDefault("templates", new ArrayList<>()); + changed += updateConfigSection("templates", embedded, user, addedTemplates); + List addedComponents = update.getAddedKeys().getOrDefault("components", new ArrayList<>()); + changed += updateConfigSection("components", embedded, user, addedComponents); + List addedFormats = update.getAddedKeys().getOrDefault("formats", new ArrayList<>()); + changed += updateStringSection("formats", embedded, user, addedFormats); + } + + user.node("file_version").set(embVersion); + try { YamlConfigurationLoader loader = YamlConfigurationLoader.builder() .file(userFile) @@ -83,12 +104,14 @@ private void updateAndSave(ConfigurationNode embedded, ConfigurationNode user, F } } - private int updateConfigSection(String name, ConfigurationNode embedded, ConfigurationNode user) throws SerializationException { + private int updateConfigSection(String name, ConfigurationNode embedded, ConfigurationNode user, List keys) throws SerializationException { + if (keys.isEmpty()) return 0; int changed = 0; if (!embedded.node(name).virtual() && !user.node(name).virtual()) { for (ConfigurationNode embSec : embedded.node(name).childrenMap().values()) { String key = (String) embSec.key(); if (key == null) continue; + if (!keys.contains(key)) continue; // Only update sections passed in the keys list if (!embSec.isMap()) continue; // User file does not have embedded key if (user.node(name).node(key).virtual()) { @@ -100,12 +123,14 @@ private int updateConfigSection(String name, ConfigurationNode embedded, Configu return changed; } - private int updateStringSection(String name, ConfigurationNode embedded, ConfigurationNode user) throws SerializationException { + private int updateStringSection(String name, ConfigurationNode embedded, ConfigurationNode user, List keys) throws SerializationException { + if (keys.isEmpty()) return 0; int changed = 0; if (!embedded.node(name).virtual() && !user.node(name).virtual()) { for (ConfigurationNode embSec : embedded.node(name).childrenMap().values()) { String key = (String) embSec.key(); if (key == null) continue; + if (!keys.contains(key)) continue; String value = embSec.getString(); if (value == null) continue; diff --git a/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/menus/MenuFileUpdates.java b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/menus/MenuFileUpdates.java new file mode 100644 index 000000000..480220137 --- /dev/null +++ b/bukkit/src/main/java/dev/aurelium/auraskills/bukkit/menus/MenuFileUpdates.java @@ -0,0 +1,52 @@ +package dev.aurelium.auraskills.bukkit.menus; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +public enum MenuFileUpdates { + + SKILLS_1("skills", 1, Map.of( + "components", List.of("skill_job_active"))), + LEVEL_PROGRESSION_1("level_progression", 1, Map.of( + "items", List.of("job"), + "components", List.of("job_select", "job_active", "job_limit"))); + + private final String menu; + private final int version; + private final Map> addedKeys; + + MenuFileUpdates(String menu, int version, Map> addedKeys) { + this.menu = menu; + this.version = version; + this.addedKeys = addedKeys; + } + + public String getMenu() { + return menu; + } + + public int getVersion() { + return version; + } + + public Map> getAddedKeys() { + return addedKeys; + } + + public static List getUpdates(String menu, int currentVersion, int updatedVersion) { + List updates = new ArrayList<>(); + for (MenuFileUpdates update : MenuFileUpdates.values()) { + if (!update.getMenu().equals(menu)) continue; + + if (update.getVersion() > currentVersion && update.getVersion() <= updatedVersion) { + updates.add(update); + } + } + // Sort by increasing version + updates.sort(Comparator.comparingInt(MenuFileUpdates::getVersion)); + return updates; + } + +} diff --git a/bukkit/src/main/resources/menus/level_progression.yml b/bukkit/src/main/resources/menus/level_progression.yml index 1dc1428c1..783f4d754 100644 --- a/bukkit/src/main/resources/menus/level_progression.yml +++ b/bukkit/src/main/resources/menus/level_progression.yml @@ -9,22 +9,22 @@ items: material: paper display_name: '{{your_ranking}}' lore: - - text: '{{rank_out_of}}' - styles: - 1: '' - 2: '' - - text: '{{rank_percent}}' - styles: - 1: '' - 2: '' - - ' ' - - '{{leaderboard_click}}' + - text: '{{rank_out_of}}' + styles: + 1: '' + 2: '' + - text: '{{rank_percent}}' + styles: + 1: '' + 2: '' + - ' ' + - '{{leaderboard_click}}' back: pos: 5,0 material: arrow display_name: '{{back}}' lore: - - '{{back_click}}' + - '{{back_click}}' close: pos: 5,1 material: barrier @@ -34,203 +34,237 @@ items: material: arrow display_name: '{{next_page}}' lore: - - '{{next_page_click}}' + - '{{next_page_click}}' previous_page: pos: 5,7 material: arrow display_name: '{{previous_page}}' lore: - - '{{previous_page_click}}' + - '{{previous_page_click}}' sources: pos: 0,2 material: experience_bottle display_name: '{{sources}}' lore: - - text: '{{sources_desc}}' - wrap: true - style: '' - - ' ' - - '{{sources_click}}' + - text: '{{sources_desc}}' + wrap: true + style: '' + - ' ' + - '{{sources_click}}' abilities: pos: 0,3 material: light_blue_dye display_name: '{{abilities}}' lore: - - text: '{{abilities_desc}} {{mana_abilities_desc}}' - wrap: true - wrap_style: 1 - styles: - 1: '' - 2: '' - 3: '' - - ' ' - - '{{abilities_click}}' + - text: '{{abilities_desc}} {{mana_abilities_desc}}' + wrap: true + wrap_style: 1 + styles: + 1: '' + 2: '' + 3: '' + - ' ' + - '{{abilities_click}}' job: pos: 0,4 material: gold_ingot display_name: '{{job}}' lore: - - text: '{{job_desc}}' - wrap: true - style: '' - - ' ' - - component: job_select - - component: job_active - - component: job_limit + - text: '{{job_desc}}' + wrap: true + style: '' + - ' ' + - component: job_select + - component: job_active + - component: job_limit templates: skill: pos: 0,0 contexts: - farming: {material: diamond_hoe, flags: [hide_attributes]} - foraging: {material: stone_axe, flags: [hide_attributes]} - mining: {material: iron_pickaxe, flags: [hide_attributes]} - fishing: {material: fishing_rod} - excavation: {material: golden_shovel, flags: [hide_attributes]} - archery: {material: bow} - defense: {material: chainmail_chestplate, flags: [hide_attributes]} - fighting: {material: diamond_sword, flags: [hide_attributes]} - endurance: {material: golden_apple} - agility: {material: feather} - alchemy: {material: potion, potion_data: {type: instant_heal}, flags: [hide_potion_effects]} - enchanting: {material: enchanting_table} - sorcery: {material: blaze_rod} - healing: {material: splash_potion, potion_data: {type: instant_heal}, flags: [hide_potion_effects]} - forging: {material: anvil} + farming: + material: iron_hoe + flags: + - hide_attributes + foraging: + material: iron_axe + flags: + - hide_attributes + mining: + material: iron_pickaxe + flags: + - hide_attributes + fishing: + material: fishing_rod + excavation: + material: iron_shovel + flags: + - hide_attributes + archery: + material: bow + defense: + material: chainmail_chestplate + flags: + - hide_attributes + fighting: + material: iron_sword + flags: + - hide_attributes + endurance: + material: golden_apple + agility: + material: feather + alchemy: + material: potion + potion_data: + type: regen + flags: + - hide_potion_effects + enchanting: + material: enchanting_table + sorcery: + material: blaze_rod + healing: + material: splash_potion + potion_data: + type: instant_heal + flags: hide_potion_effects + forging: + material: anvil display_name: '{skill} {level}' lore: - - text: '{desc}' - wrap: true - style: '' - - component: stats_leveled - - component: ability_levels - - component: mana_ability_info - - ' ' - - component: progress - - component: max_level + - text: '{desc}' + wrap: true + style: '' + - component: stats_leveled + - component: ability_levels + - component: mana_ability_info + - ' ' + - component: progress + - component: max_level unlocked: material: lime_stained_glass_pane display_name: '{{level}} {level}' lore: - - '{{level}} {level}' - - component: rewards - - component: ability_unlock - - component: ability_level - - component: mana_ability_unlock - - component: mana_ability_level - - ' ' - - '{{unlocked}}' + - '{{level}} {level}' + - component: rewards + - component: ability_unlock + - component: ability_level + - component: mana_ability_unlock + - component: mana_ability_level + - ' ' + - '{{unlocked}}' in_progress: material: yellow_stained_glass_pane display_name: '{{level}} {level}' lore: - - '{{level}} {level}' - - component: rewards - - component: ability_unlock - - component: ability_level - - component: mana_ability_unlock - - component: mana_ability_level - - ' ' - - '{{progress}}: {percent}%' - - '{bar}' - - '{current_xp}/{level_xp} {xp_unit}' - - ' ' - - '{{in_progress}}' + - '{{level}} {level}' + - component: rewards + - component: ability_unlock + - component: ability_level + - component: mana_ability_unlock + - component: mana_ability_level + - ' ' + - '{{progress}}: {percent}%' + - '{bar}' + - '{current_xp}/{level_xp} {xp_unit}' + - ' ' + - '{{in_progress}}' locked: material: red_stained_glass_pane display_name: '{{level}} {level}' lore: - - '{{level}} {level}' - - component: rewards - - component: ability_unlock - - component: ability_level - - component: mana_ability_unlock - - component: mana_ability_level - - ' ' - - '{{locked}}' + - '{{level}} {level}' + - component: rewards + - component: ability_unlock + - component: ability_level + - component: mana_ability_unlock + - component: mana_ability_level + - ' ' + - '{{locked}}' components: stats_leveled: context: Skill lore: - - ' ' - - '{{stats_leveled}}: {entries[, ]}' + - ' ' + - '{{stats_leveled}}: {entries[, ]}' ability_levels: context: Skill lore: - - ' ' - - '{{ability_levels}}: {entries[]}' + - ' ' + - '{{ability_levels}}: {entries[]}' mana_ability_info: context: Skill lore: - - ' ' - - '{{mana_ability}} {name} {level}' - - ' {entries[\n ](3)}' + - ' ' + - '{{mana_ability}} {name} {level}' + - ' {entries[\n ](3)}' progress: context: Skill lore: - - '{{progress_to_level}} {next_level}: {percent}%' - - '{bar}' - - '{current_xp}/{level_xp} {xp_unit}' + - '{{progress_to_level}} {next_level}: {percent}%' + - '{bar}' + - '{current_xp}/{level_xp} {xp_unit}' max_level: context: Skill lore: - - '{{max_level}}' + - '{{max_level}}' rewards: context: Integer lore: - - '{{rewards}}: {entries[]}' + - '{{rewards}}: {entries[]}' ability_unlock: context: Integer lore: - - ' ' - - '{name} {{ability_unlock}}' - - text: '{desc}' - wrap: true - wrap_indent: ' ' - style: '' + - ' ' + - '{name} {{ability_unlock}}' + - text: '{desc}' + wrap: true + wrap_indent: ' ' + style: '' ability_level: context: Integer lore: - - ' ' - - '{name} {level}' - - text: '{desc}' - wrap: true - wrap_indent: ' ' - style: '' + - ' ' + - '{name} {level}' + - text: '{desc}' + wrap: true + wrap_indent: ' ' + style: '' mana_ability_unlock: context: Integer lore: - - ' ' - - '{name} {{mana_ability_unlock}}' - - text: '{desc}' - wrap: true - wrap_indent: ' ' - styles: - 0: '' - 1: '' + - ' ' + - '{name} {{mana_ability_unlock}}' + - text: '{desc}' + wrap: true + wrap_indent: ' ' + styles: + 0: '' + 1: '' mana_ability_level: context: Integer lore: - - ' ' - - '{name} {level}' - - text: '{desc}' - wrap: true - wrap_indent: ' ' - styles: - 0: '' - 1: '' + - ' ' + - '{name} {level}' + - text: '{desc}' + wrap: true + wrap_indent: ' ' + styles: + 0: '' + 1: '' job_select: lore: - - '{{job_select}}' + - '{{job_select}}' job_active: lore: - - '{{job_active}}' - - ' ' - - '{{job_quit}}' + - '{{job_active}}' + - ' ' + - '{{job_quit}}' job_limit: lore: - - text: '{{job_limit}}' - wrap: true - style: '' + - text: '{{job_limit}}' + wrap: true + style: '' formats: stat_leveled_entry: '{color}{stat}' unlocked_ability_entry: '\n {name} {level} ({info})' @@ -249,4 +283,5 @@ options: over_max_stack_amount: 1 items_per_page: 24 start_level: 1 - track: [9, 18, 27, 36, 37, 38, 29, 20, 11, 12, 13, 22, 31, 40, 41, 42, 33, 24, 15, 16, 17, 26, 35, 44] \ No newline at end of file + track: [9, 18, 27, 36, 37, 38, 29, 20, 11, 12, 13, 22, 31, 40, 41, 42, 33, 24, 15, 16, 17, 26, 35, 44] +file_version: 1 \ No newline at end of file diff --git a/bukkit/src/main/resources/menus/skills.yml b/bukkit/src/main/resources/menus/skills.yml index f92fd4476..515bc260d 100644 --- a/bukkit/src/main/resources/menus/skills.yml +++ b/bukkit/src/main/resources/menus/skills.yml @@ -11,16 +11,16 @@ items: base64: eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMjcwNWZkOTRhMGM0MzE5MjdmYjRlNjM5YjBmY2ZiNDk3MTdlNDEyMjg1YTAyYjQzOWUwMTEyZGEyMmIyZTJlYyJ9fX0= display_name: '{{your_skills}} - {player}' lore: - - text: '{{your_skills_desc}}' - wrap: true - style: '' - - ' ' - - text: '{{your_skills_hover}}' - wrap: true - style: '' - - text: '{{your_skills_click}}' - wrap: true - style: '' + - text: '{{your_skills_desc}}' + wrap: true + style: '' + - ' ' + - text: '{{your_skills_hover}}' + wrap: true + style: '' + - text: '{{your_skills_click}}' + wrap: true + style: '' close: pos: 4,8 material: barrier @@ -30,27 +30,91 @@ items: material: player_head display_name: '{{stats}}' lore: - - '{{stats_desc}}' - - ' ' - - '{{stats_click}}' + - '{{stats_desc}}' + - ' ' + - '{{stats_click}}' templates: skill: contexts: - archery: { group: first_row, order: 1, material: bow } - fighting: { group: first_row, order: 2, material: iron_sword, flags: [ hide_attributes ] } - defense: { group: first_row, order: 3, material: chainmail_chestplate, flags: [ hide_attributes ] } - endurance: {group: first_row, order: 4, material: golden_apple} - farming: {group: second_row, order: 1, material: iron_hoe, flags: [hide_attributes]} - foraging: {group: second_row, order: 2, material: iron_axe, flags: [hide_attributes]} - mining: {group: second_row, order: 3, material: iron_pickaxe, flags: [hide_attributes]} - fishing: {group: second_row, order: 4, material: fishing_rod} - excavation: {group: second_row, order: 5, material: iron_shovel, flags: [hide_attributes]} - agility: {group: third_row, order: 1, material: feather} - alchemy: {group: third_row, order: 2, material: potion, potion_data: {type: regen}, flags: [hide_potion_effects]} - enchanting: {group: third_row, order: 3, material: enchanting_table} - sorcery: {group: third_row, order: 4, material: blaze_rod} - healing: {group: third_row, order: 5, material: splash_potion, potion_data: {type: instant_heal}, flags: [hide_potion_effects]} - forging: {group: third_row, order: 6, material: anvil} + archery: + group: first_row + order: 1 + material: bow + fighting: + group: first_row + order: 2 + material: iron_sword + flags: + - hide_attributes + defense: + group: first_row + order: 3 + material: chainmail_chestplate + flags: hide_attributes + endurance: + group: first_row + order: 4 + material: golden_apple + farming: + group: second_row + order: 1 + material: iron_hoe + flags: + - hide_attributes + foraging: + group: second_row + order: 2 + material: iron_axe + flags: + - hide_attributes + mining: + group: second_row + order: 3 + material: iron_pickaxe + flags: + - hide_attributes + fishing: + group: second_row + order: 4 + material: fishing_rod + excavation: + group: second_row + order: 5 + material: iron_shovel + flags: + - hide_attributes + agility: + group: third_row + order: 1 + material: feather + alchemy: + group: third_row + order: 2 + material: potion + potion_data: + type: regen + flags: + - hide_potion_effects + enchanting: + group: third_row + order: 3 + material: enchanting_table + sorcery: + group: third_row + order: 4 + material: blaze_rod + healing: + group: third_row + order: 5 + material: splash_potion + potion_data: + type: instant_heal + flags: + - hide_potion_effects + forging: + group: third_row + order: 6 + material: anvil groups: first_row: start: 1,0 @@ -66,50 +130,50 @@ templates: align: center display_name: '{skill} {level}' lore: - - text: '{desc}' - wrap: true - style: '' - - component: stats_leveled - - component: ability_levels - - component: mana_ability_info - - ' ' - - component: progress - - component: max_level - - component: skill_job_active - - ' ' - - '{{skill_click}}' + - text: '{desc}' + wrap: true + style: '' + - component: stats_leveled + - component: ability_levels + - component: mana_ability_info + - ' ' + - component: progress + - component: max_level + - component: skill_job_active + - ' ' + - '{{skill_click}}' components: stats_leveled: context: Skill lore: - - ' ' - - '{{stats_leveled}}: {entries[, ]}' + - ' ' + - '{{stats_leveled}}: {entries[, ]}' ability_levels: context: Skill lore: - - ' ' - - '{{ability_levels}}: {entries[]}' + - ' ' + - '{{ability_levels}}: {entries[]}' mana_ability_info: context: Skill lore: - - ' ' - - '{{mana_ability}} {name} {level}' - - ' {entries[\n ](3)}' + - ' ' + - '{{mana_ability}} {name} {level}' + - ' {entries[\n ](3)}' progress: context: Skill lore: - - '{{progress_to_level}} {next_level}: {percent}%' - - '{bar}' - - '{current_xp}/{level_xp} {xp_unit}' + - '{{progress_to_level}} {next_level}: {percent}%' + - '{bar}' + - '{current_xp}/{level_xp} {xp_unit}' max_level: context: Skill lore: - - '{{max_level}}' + - '{{max_level}}' skill_job_active: context: Skill lore: - - ' ' - - '{{active_job}}' + - ' ' + - '{{active_job}}' formats: stat_leveled_entry: '{color}{stat}' unlocked_ability_entry: '\n {name} {level} ({info})' @@ -125,4 +189,5 @@ formats: bar_current: '■' bar_remaining: '■' options: - bar_length: 20 \ No newline at end of file + bar_length: 20 +file_version: 1 \ No newline at end of file