diff --git a/src/main/java/dev/esophose/playerparticles/command/DefaultCommandModule.java b/src/main/java/dev/esophose/playerparticles/command/DefaultCommandModule.java index 34fd499..afcaec0 100644 --- a/src/main/java/dev/esophose/playerparticles/command/DefaultCommandModule.java +++ b/src/main/java/dev/esophose/playerparticles/command/DefaultCommandModule.java @@ -12,7 +12,7 @@ public class DefaultCommandModule implements CommandModule { public void onCommandExecute(PPlayer pplayer, String[] args) { // The default command just opens the GUI, execute the GUICommandModule ((GUICommandModule) PlayerParticles.getInstance().getManager(CommandManager.class).findMatchingCommand("gui")) - .onCommandExecute(pplayer, false); + .onCommandExecute(pplayer, new String[0], false); } public List onTabComplete(PPlayer pplayer, String[] args) { diff --git a/src/main/java/dev/esophose/playerparticles/command/GUICommandModule.java b/src/main/java/dev/esophose/playerparticles/command/GUICommandModule.java index 854fadd..7d59a3a 100644 --- a/src/main/java/dev/esophose/playerparticles/command/GUICommandModule.java +++ b/src/main/java/dev/esophose/playerparticles/command/GUICommandModule.java @@ -7,16 +7,17 @@ import dev.esophose.playerparticles.manager.LocaleManager; import dev.esophose.playerparticles.manager.PermissionManager; import dev.esophose.playerparticles.particles.PPlayer; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import org.bukkit.Bukkit; +import org.bukkit.util.StringUtil; public class GUICommandModule implements CommandModule { public void onCommandExecute(PPlayer pplayer, String[] args) { - this.onCommandExecute(pplayer, true); + this.onCommandExecute(pplayer, args, true); } - public void onCommandExecute(PPlayer pplayer, boolean openedFromGuiCommand) { + public void onCommandExecute(PPlayer pplayer, String[] args, boolean openedFromGuiCommand) { PermissionManager permissionManager = PlayerParticles.getInstance().getManager(PermissionManager.class); LocaleManager localeManager = PlayerParticles.getInstance().getManager(LocaleManager.class); GuiManager guiManager = PlayerParticles.getInstance().getManager(GuiManager.class); @@ -45,11 +46,20 @@ public class GUICommandModule implements CommandModule { return; } - Bukkit.getScheduler().runTask(PlayerParticles.getInstance(), () -> guiManager.openDefault(pplayer)); + if (args.length > 0 && args[0].equalsIgnoreCase("presets")) { + guiManager.openPresetGroups(pplayer); + } else { + guiManager.openDefault(pplayer); + } } public List onTabComplete(PPlayer pplayer, String[] args) { - return new ArrayList<>(); + List completions = new ArrayList<>(); + if (args.length == 1) { + List possibilities = Collections.singletonList("presets"); + StringUtil.copyPartialMatches(args[0], possibilities, completions); + } + return completions; } public String getName() { diff --git a/src/main/java/dev/esophose/playerparticles/database/migrations/_2_PresetGroupsGuiSections.java b/src/main/java/dev/esophose/playerparticles/database/migrations/_2_PresetGroupsGuiSections.java deleted file mode 100644 index 5030475..0000000 --- a/src/main/java/dev/esophose/playerparticles/database/migrations/_2_PresetGroupsGuiSections.java +++ /dev/null @@ -1,137 +0,0 @@ -package dev.esophose.playerparticles.database.migrations; - -import dev.esophose.playerparticles.PlayerParticles; -import dev.esophose.playerparticles.config.CommentedConfigurationSection; -import dev.esophose.playerparticles.config.CommentedFileConfiguration; -import dev.esophose.playerparticles.database.DataMigration; -import dev.esophose.playerparticles.database.DatabaseConnector; -import dev.esophose.playerparticles.manager.ParticleGroupPresetManager; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.sql.Connection; -import java.util.ArrayList; -import java.util.List; - -public class _2_PresetGroupsGuiSections extends DataMigration { - - private final PlayerParticles playerParticles; - - public _2_PresetGroupsGuiSections(PlayerParticles playerParticles) { - super(2); - - this.playerParticles = playerParticles; - } - - @Override - public void migrate(DatabaseConnector connector, Connection connection, String tablePrefix) { - File presetsFile = new File(this.playerParticles.getDataFolder(), ParticleGroupPresetManager.FILE_NAME); - if (!presetsFile.exists()) - return; - - // Convert existing preset_groups.yml into the new format - CommentedFileConfiguration presetsConfig = CommentedFileConfiguration.loadConfiguration(this.playerParticles, presetsFile); - List existingPresets = new ArrayList<>(); - - for (String groupName : presetsConfig.getKeys(false)) { - CommentedConfigurationSection groupSection = presetsConfig.getConfigurationSection(groupName); - String displayName = groupSection.getString("display-name"); - String guiIcon = groupSection.getString("gui-icon"); - String permission = groupSection.getString("permission"); - boolean allowPermissionOverride = groupSection.getBoolean("allow-permission-override"); - List particleData = new ArrayList<>(); - for (String key : groupSection.getKeys(false)) { - try { - int id = Integer.parseInt(key); - CommentedConfigurationSection particleGroup = groupSection.getConfigurationSection(key); - String effect = particleGroup.getString("effect"); - String style = particleGroup.getString("style"); - String data = particleGroup.getString("data"); - particleData.add(new ParticleData(id, effect, style, data)); - } catch (NumberFormatException ignored) { } - } - existingPresets.add(new PresetData(groupName, displayName, guiIcon, permission, allowPermissionOverride, particleData)); - } - - // Delete existing file, going to overwrite it all - presetsFile.delete(); - - // Copy over the new file - try (InputStream inStream = PlayerParticles.getInstance().getResource(ParticleGroupPresetManager.FILE_NAME)) { - Files.copy(inStream, Paths.get(presetsFile.getAbsolutePath())); - } catch (IOException e) { - e.printStackTrace(); - } - - // Reload the config - presetsConfig.reloadConfig(); - - // Delete everything in the presets section - presetsConfig.set("page1.presets", null); - - // Recreate presets section - CommentedConfigurationSection presetsSection = presetsConfig.createSection("page1.presets"); - - // Fill the data back in - int slot = 10; - int nextWrap = 17; - int maxSlot = 43; - - for (PresetData presetData : existingPresets) { - CommentedConfigurationSection presetSection = presetsSection.createSection(presetData.groupName); - presetSection.set("display-name", presetData.displayName); - presetSection.set("gui-icon", presetData.guiIcon); - presetSection.set("gui-slot", slot); - presetSection.set("permission", presetData.permission); - presetSection.set("allow-permission-override", presetData.allowPermissionOverride); - - for (ParticleData particleData : presetData.particleData) { - CommentedConfigurationSection particleSection = presetSection.createSection(String.valueOf(particleData.id)); - particleSection.set("effect", particleData.effect); - particleSection.set("style", particleData.style); - particleSection.set("data", particleData.data); - } - - slot++; - if (slot == nextWrap) { // Loop around border - nextWrap += 9; - slot += 2; - } - // Overflowed the available space - if (slot > maxSlot) - slot = maxSlot; - } - - presetsConfig.save(); - } - - private static class PresetData { - private final String groupName, displayName, guiIcon, permission; - private final boolean allowPermissionOverride; - private final List particleData; - - private PresetData(String groupName, String displayName, String guiIcon, String permission, boolean allowPermissionOverride, List particleData) { - this.groupName = groupName; - this.displayName = displayName; - this.guiIcon = guiIcon; - this.permission = permission; - this.allowPermissionOverride = allowPermissionOverride; - this.particleData = particleData; - } - } - - private static class ParticleData { - private final int id; - private final String effect, style, data; - - private ParticleData(int id, String effect, String style, String data) { - this.id = id; - this.effect = effect; - this.style = style; - this.data = data; - } - } - -} diff --git a/src/main/java/dev/esophose/playerparticles/gui/GuiInventoryEditData.java b/src/main/java/dev/esophose/playerparticles/gui/GuiInventoryEditData.java index 090627c..d35e29e 100644 --- a/src/main/java/dev/esophose/playerparticles/gui/GuiInventoryEditData.java +++ b/src/main/java/dev/esophose/playerparticles/gui/GuiInventoryEditData.java @@ -152,7 +152,7 @@ public class GuiInventoryEditData extends GuiInventory { if (pe == ParticleEffect.NOTE) { // Note data this.populateNoteData(editingParticle, pageNumber, callbackList, callbackListPosition); } else { // Color data - this.populateColorData(editingParticle, pageNumber, callbackList, callbackListPosition); + this.populateColorData(editingParticle, callbackList, callbackListPosition); } } else if (pe.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) { if (pe == ParticleEffect.ITEM) { // Item data @@ -178,11 +178,10 @@ public class GuiInventoryEditData extends GuiInventory { * Populates the Inventory with available color data options * * @param editingParticle The ParticlePair that's being edited - * @param pageNumber The current page number * @param callbackList The List of GuiInventoryEditFinishedCallbacks * @param callbackListPosition The index of the callbackList we're currently at */ - private void populateColorData(ParticlePair editingParticle, int pageNumber, List callbackList, int callbackListPosition) { + private void populateColorData(ParticlePair editingParticle, List callbackList, int callbackListPosition) { LocaleManager localeManager = PlayerParticles.getInstance().getManager(LocaleManager.class); int index = 10; diff --git a/src/main/java/dev/esophose/playerparticles/gui/GuiInventoryLoadPresetGroups.java b/src/main/java/dev/esophose/playerparticles/gui/GuiInventoryLoadPresetGroups.java index 62b6586..70307c3 100644 --- a/src/main/java/dev/esophose/playerparticles/gui/GuiInventoryLoadPresetGroups.java +++ b/src/main/java/dev/esophose/playerparticles/gui/GuiInventoryLoadPresetGroups.java @@ -23,7 +23,7 @@ import org.bukkit.Bukkit; public class GuiInventoryLoadPresetGroups extends GuiInventory { public GuiInventoryLoadPresetGroups(PPlayer pplayer, boolean isEndPoint, int pageNumber) { - super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, PlayerParticles.getInstance().getManager(ParticleGroupPresetManager.class).getPresetGroupPages().get(pageNumber).getTitle())); + super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, PlayerParticles.getInstance().getManager(ParticleGroupPresetManager.class).getPresetGroupPages(pplayer).get(pageNumber).getTitle())); PlayerParticles playerParticles = PlayerParticles.getInstance(); ParticleGroupPresetManager presetManager = playerParticles.getManager(ParticleGroupPresetManager.class); @@ -32,11 +32,10 @@ public class GuiInventoryLoadPresetGroups extends GuiInventory { this.fillBorder(BorderColor.GREEN); - ParticleGroupPresetPage pageInfo = presetManager.getPresetGroupPages().get(pageNumber); - List groups = pageInfo.getPresets(); + ParticleGroupPresetPage pageInfo = presetManager.getPresetGroupPages(pplayer).get(pageNumber); Map extraBorder = pageInfo.getExtraBorder(); - int maxPages = presetManager.getMaxPageNumber(); + int maxPages = presetManager.getMaxPageNumber(pplayer); // Fill borders extraBorder.forEach((item, color) -> this.inventory.setItem(item, color.getIcon())); diff --git a/src/main/java/dev/esophose/playerparticles/locale/EnglishLocale.java b/src/main/java/dev/esophose/playerparticles/locale/EnglishLocale.java index eb14194..3f56037 100644 --- a/src/main/java/dev/esophose/playerparticles/locale/EnglishLocale.java +++ b/src/main/java/dev/esophose/playerparticles/locale/EnglishLocale.java @@ -276,6 +276,7 @@ public class EnglishLocale implements Locale { this.put("gui-manage-your-groups-description", "Create, delete, and load your particle groups"); this.put("#31", "GUI Load Messages"); + this.put("gui-load-a-preset-group", "Load A Preset Group"); this.put("gui-load-a-preset-group-description", "Load a premade particle group"); this.put("#32", "GUI Save Messages"); diff --git a/src/main/java/dev/esophose/playerparticles/locale/FrenchLocale.java b/src/main/java/dev/esophose/playerparticles/locale/FrenchLocale.java index 9a7cf3d..8444b6c 100644 --- a/src/main/java/dev/esophose/playerparticles/locale/FrenchLocale.java +++ b/src/main/java/dev/esophose/playerparticles/locale/FrenchLocale.java @@ -276,6 +276,7 @@ public class FrenchLocale implements Locale { this.put("gui-manage-your-groups-description", "Créez, éditez, et supprimez vos groupes particules"); this.put("#31", "GUI Load Messages"); + this.put("gui-load-a-preset-group", "Chargez un groupe de presets"); this.put("gui-load-a-preset-group-description", "Chargez un groupe de particules déjà fait"); this.put("#32", "GUI Save Messages"); diff --git a/src/main/java/dev/esophose/playerparticles/locale/GermanLocale.java b/src/main/java/dev/esophose/playerparticles/locale/GermanLocale.java index 89583ae..fcaf087 100644 --- a/src/main/java/dev/esophose/playerparticles/locale/GermanLocale.java +++ b/src/main/java/dev/esophose/playerparticles/locale/GermanLocale.java @@ -276,6 +276,7 @@ public class GermanLocale implements Locale { this.put("gui-manage-your-groups-description", "Erstellen, löschen und laden Sie Ihre Partikelgruppen"); this.put("#31", "GUI Load Messages"); + this.put("gui-load-a-preset-group", "Laden Sie eine vorgefertigte Gruppe"); this.put("gui-load-a-preset-group-description", "Laden Sie eine vorgefertigte Partikelgruppe"); this.put("#32", "GUI Save Messages"); diff --git a/src/main/java/dev/esophose/playerparticles/locale/RussianLocale.java b/src/main/java/dev/esophose/playerparticles/locale/RussianLocale.java index 106bfae..3c382d4 100644 --- a/src/main/java/dev/esophose/playerparticles/locale/RussianLocale.java +++ b/src/main/java/dev/esophose/playerparticles/locale/RussianLocale.java @@ -276,6 +276,7 @@ public class RussianLocale implements Locale { this.put("gui-manage-your-groups-description", "Создание, изменение и удаление Ваших групп"); this.put("#31", "GUI Load Messages"); + this.put("gui-load-a-preset-group", "Установить группу"); this.put("gui-load-a-preset-group-description", "Установка готовой группы частиц"); this.put("#32", "GUI Save Messages"); diff --git a/src/main/java/dev/esophose/playerparticles/locale/SimplifiedChineseLocale.java b/src/main/java/dev/esophose/playerparticles/locale/SimplifiedChineseLocale.java index 6d3d393..638a69b 100644 --- a/src/main/java/dev/esophose/playerparticles/locale/SimplifiedChineseLocale.java +++ b/src/main/java/dev/esophose/playerparticles/locale/SimplifiedChineseLocale.java @@ -276,6 +276,7 @@ public class SimplifiedChineseLocale implements Locale { this.put("gui-manage-your-groups-description", "创建、删除和加载你的粒子组"); this.put("#31", "GUI Load Messages"); + this.put("gui-load-a-preset-group", "加载预设粒子组"); this.put("gui-load-a-preset-group-description", "加载预设粒子组"); this.put("#32", "GUI Save Messages"); diff --git a/src/main/java/dev/esophose/playerparticles/locale/VietnameseLocale.java b/src/main/java/dev/esophose/playerparticles/locale/VietnameseLocale.java index 7dd0948..ca3f94c 100644 --- a/src/main/java/dev/esophose/playerparticles/locale/VietnameseLocale.java +++ b/src/main/java/dev/esophose/playerparticles/locale/VietnameseLocale.java @@ -276,6 +276,7 @@ public class VietnameseLocale implements Locale { this.put("gui-manage-your-groups-description", "Tạo, xóa, và tải Group Hạt hiệu ứng của bạn"); this.put("#31", "GUI Load Messages"); + this.put("gui-load-a-preset-group", "Tải một Preset Group"); this.put("gui-load-a-preset-group-description", "Tải Group Hạt hiệu ứng có sẵn"); this.put("#32", "GUI Save Messages"); diff --git a/src/main/java/dev/esophose/playerparticles/manager/DataMigrationManager.java b/src/main/java/dev/esophose/playerparticles/manager/DataMigrationManager.java index b4a0879..c6632d4 100644 --- a/src/main/java/dev/esophose/playerparticles/manager/DataMigrationManager.java +++ b/src/main/java/dev/esophose/playerparticles/manager/DataMigrationManager.java @@ -5,7 +5,6 @@ import dev.esophose.playerparticles.database.DataMigration; import dev.esophose.playerparticles.database.DatabaseConnector; import dev.esophose.playerparticles.database.SQLiteConnector; import dev.esophose.playerparticles.database.migrations._1_InitialMigration; -import dev.esophose.playerparticles.database.migrations._2_PresetGroupsGuiSections; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Arrays; @@ -21,8 +20,7 @@ public class DataMigrationManager extends Manager { super(playerParticles); this.migrations = Arrays.asList( - new _1_InitialMigration(), - new _2_PresetGroupsGuiSections(this.playerParticles) + new _1_InitialMigration() ); } diff --git a/src/main/java/dev/esophose/playerparticles/manager/GuiManager.java b/src/main/java/dev/esophose/playerparticles/manager/GuiManager.java index 4b8c7f2..13840ec 100644 --- a/src/main/java/dev/esophose/playerparticles/manager/GuiManager.java +++ b/src/main/java/dev/esophose/playerparticles/manager/GuiManager.java @@ -109,17 +109,34 @@ public class GuiManager extends Manager implements Listener, Runnable { * @param pplayer The PPlayer to open the GUI screen for */ public void openDefault(PPlayer pplayer) { - Bukkit.getScheduler().runTask(this.playerParticles, () -> { - GuiInventory inventoryToOpen; - if (!Setting.GUI_PRESETS_ONLY.getBoolean()) { - inventoryToOpen = new GuiInventoryDefault(pplayer); - } else { - inventoryToOpen = new GuiInventoryLoadPresetGroups(pplayer, true, 1); - } + if (Setting.GUI_PRESETS_ONLY.getBoolean()) { + this.openPresetGroups(pplayer); + return; + } - pplayer.getPlayer().openInventory(inventoryToOpen.getInventory()); - this.guiInventories.add(inventoryToOpen); - }); + Bukkit.getScheduler().runTask(this.playerParticles, () -> + this.openGui(pplayer, new GuiInventoryDefault(pplayer))); + } + + /** + * Opens the preset groups GUI screen for a player + * + * @param pplayer The PPlayer to open the GUI screen for + */ + public void openPresetGroups(PPlayer pplayer) { + Bukkit.getScheduler().runTask(this.playerParticles, () -> + this.openGui(pplayer, new GuiInventoryLoadPresetGroups(pplayer, true, 1))); + } + + /** + * Opens a GUI screen for a player + * + * @param pplayer The PPlayer to open for + * @param guiInventory The GuiInventory to open + */ + private void openGui(PPlayer pplayer, GuiInventory guiInventory) { + pplayer.getPlayer().openInventory(guiInventory.getInventory()); + this.guiInventories.add(guiInventory); } /** diff --git a/src/main/java/dev/esophose/playerparticles/manager/ParticleGroupPresetManager.java b/src/main/java/dev/esophose/playerparticles/manager/ParticleGroupPresetManager.java index 564e2b6..c99f569 100644 --- a/src/main/java/dev/esophose/playerparticles/manager/ParticleGroupPresetManager.java +++ b/src/main/java/dev/esophose/playerparticles/manager/ParticleGroupPresetManager.java @@ -1,6 +1,8 @@ package dev.esophose.playerparticles.manager; import dev.esophose.playerparticles.PlayerParticles; +import dev.esophose.playerparticles.config.CommentedConfigurationSection; +import dev.esophose.playerparticles.config.CommentedFileConfiguration; import dev.esophose.playerparticles.gui.GuiInventory.BorderColor; import dev.esophose.playerparticles.particles.PPlayer; import dev.esophose.playerparticles.particles.ParticleEffect; @@ -20,6 +22,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -27,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.IntStream; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; @@ -52,144 +56,153 @@ public class ParticleGroupPresetManager extends Manager { if (!pluginDataFolder.exists()) pluginDataFolder.mkdir(); - File groupsFile = new File(pluginDataFolder, FILE_NAME); + File presetsFile = new File(pluginDataFolder, FILE_NAME); // Create the file if it doesn't exist - if (!groupsFile.exists()) { + if (!presetsFile.exists()) { try (InputStream inStream = PlayerParticles.getInstance().getResource(FILE_NAME)) { - Files.copy(inStream, Paths.get(groupsFile.getAbsolutePath())); + Files.copy(inStream, Paths.get(presetsFile.getAbsolutePath())); } catch (IOException e) { e.printStackTrace(); } + } else { + this.tryMigrateOld(presetsFile); } // Parse groups.yml file - YamlConfiguration groupsYaml = YamlConfiguration.loadConfiguration(groupsFile); - int pageNumber = 1; - for (String pageKey: groupsYaml.getKeys(false)) { - ConfigurationSection pageSection = groupsYaml.getConfigurationSection(pageKey); - String title = HexUtils.colorify(pageSection.getString("title")); - ConfigurationSection presetsSection = pageSection.getConfigurationSection("presets"); - List presets = new ArrayList<>(); - for (String groupName : presetsSection.getKeys(false)) { - Map particles = new HashMap<>(); - String displayName = ""; - Material guiIcon = Material.ENDER_CHEST; - int guiSlot = -1; - String permission = ""; - boolean allowPermissionOverride = false; - ConfigurationSection groupSection = presetsSection.getConfigurationSection(groupName); + try { + YamlConfiguration groupsYaml = YamlConfiguration.loadConfiguration(presetsFile); + int pageNumber = 1; + for (String pageKey: groupsYaml.getKeys(false)) { + ConfigurationSection pageSection = groupsYaml.getConfigurationSection(pageKey); + String title = HexUtils.colorify(pageSection.getString("title")); + ConfigurationSection presetsSection = pageSection.getConfigurationSection("presets"); + List presets = new ArrayList<>(); + if (presetsSection != null) { + for (String groupName : presetsSection.getKeys(false)) { + Map particles = new HashMap<>(); + String displayName = ""; + Material guiIcon = Material.ENDER_CHEST; + int guiSlot = -1; + String permission = ""; + boolean allowPermissionOverride = false; + ConfigurationSection groupSection = presetsSection.getConfigurationSection(groupName); - Set particleKeys = groupSection.getKeys(false); - for (String stringId : particleKeys) { - if (stringId.equalsIgnoreCase("display-name")) { - displayName = groupSection.getString(stringId); - continue; - } + Set particleKeys = groupSection.getKeys(false); + for (String stringId : particleKeys) { + if (stringId.equalsIgnoreCase("display-name")) { + displayName = groupSection.getString(stringId); + continue; + } - if (stringId.equalsIgnoreCase("gui-icon")) { - guiIcon = Material.matchMaterial(groupSection.getString(stringId)); - continue; - } + if (stringId.equalsIgnoreCase("gui-icon")) { + guiIcon = Material.matchMaterial(groupSection.getString(stringId)); + continue; + } - if (stringId.equalsIgnoreCase("gui-slot")) { - guiSlot = groupSection.getInt(stringId); - continue; - } + if (stringId.equalsIgnoreCase("gui-slot")) { + guiSlot = groupSection.getInt(stringId); + continue; + } - if (stringId.equalsIgnoreCase("permission")) { - permission = groupSection.getString(stringId); - continue; - } + if (stringId.equalsIgnoreCase("permission")) { + permission = groupSection.getString(stringId); + continue; + } - if (stringId.equalsIgnoreCase("allow-permission-override")) { - allowPermissionOverride = groupSection.getBoolean(stringId); - continue; - } + if (stringId.equalsIgnoreCase("allow-permission-override")) { + allowPermissionOverride = groupSection.getBoolean(stringId); + continue; + } - ConfigurationSection particleSection = groupSection.getConfigurationSection(stringId); + ConfigurationSection particleSection = groupSection.getConfigurationSection(stringId); - int id = Integer.parseInt(stringId); - ParticleEffect effect = new InputParser(null, new String[] { particleSection.getString("effect") }).next(ParticleEffect.class); - ParticleStyle style = new InputParser(null, new String[] { particleSection.getString("style") }).next(ParticleStyle.class); + int id = Integer.parseInt(stringId); + ParticleEffect effect = new InputParser(null, new String[] { particleSection.getString("effect") }).next(ParticleEffect.class); + ParticleStyle style = new InputParser(null, new String[] { particleSection.getString("style") }).next(ParticleStyle.class); - if (effect == null) { - PlayerParticles.getInstance().getLogger().severe("Invalid effect name: '" + particleSection.getString("effect") + "'!"); - continue; - } + if (effect == null) { + PlayerParticles.getInstance().getLogger().severe("Invalid effect name: '" + particleSection.getString("effect") + "'!"); + continue; + } - if (style == null) { - PlayerParticles.getInstance().getLogger().severe("Invalid style name: '" + particleSection.getString("style") + "'!"); - continue; - } + if (style == null) { + PlayerParticles.getInstance().getLogger().severe("Invalid style name: '" + particleSection.getString("style") + "'!"); + continue; + } - Material itemData = null; - Material blockData = null; - OrdinaryColor colorData = null; - NoteColor noteColorData = null; + Material itemData = null; + Material blockData = null; + OrdinaryColor colorData = null; + NoteColor noteColorData = null; - String dataString = particleSection.getString("data"); - if (dataString != null && !dataString.isEmpty()) { - String[] args = dataString.split(" "); - InputParser inputParser = new InputParser(null, args); + String dataString = particleSection.getString("data"); + if (dataString != null && !dataString.isEmpty()) { + String[] args = dataString.split(" "); + InputParser inputParser = new InputParser(null, args); - if (effect.hasProperty(ParticleProperty.COLORABLE)) { - if (effect == ParticleEffect.NOTE) { - noteColorData = inputParser.next(NoteColor.class); - if (noteColorData == null) { - PlayerParticles.getInstance().getLogger().severe("Invalid note: '" + dataString + "'!"); - continue; + if (effect.hasProperty(ParticleProperty.COLORABLE)) { + if (effect == ParticleEffect.NOTE) { + noteColorData = inputParser.next(NoteColor.class); + if (noteColorData == null) { + PlayerParticles.getInstance().getLogger().severe("Invalid note: '" + dataString + "'!"); + continue; + } + } else { + colorData = inputParser.next(OrdinaryColor.class); + if (colorData == null) { + PlayerParticles.getInstance().getLogger().severe("Invalid color: '" + dataString + "'!"); + continue; + } + } + } else if (effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) { + if (effect == ParticleEffect.BLOCK || effect == ParticleEffect.FALLING_DUST) { + blockData = inputParser.next(Material.class); + if (blockData == null || !blockData.isBlock()) { + PlayerParticles.getInstance().getLogger().severe("Invalid block: '" + dataString + "'!"); + continue; + } + } else if (effect == ParticleEffect.ITEM) { + itemData = inputParser.next(Material.class); + if (itemData == null || itemData.isBlock()) { + PlayerParticles.getInstance().getLogger().severe("Invalid item: '" + dataString + "'!"); + continue; + } + } } + } + + particles.put(id, new ParticlePair(null, id, effect, style, itemData, blockData, colorData, noteColorData)); + } + + presets.add(new ParticleGroupPreset(HexUtils.colorify(displayName), guiIcon, guiSlot, permission, allowPermissionOverride, new ParticleGroup(groupName, particles))); + } + } + + Map extra = new HashMap<>(); + ConfigurationSection extraSection = pageSection.getConfigurationSection("extra"); + if (extraSection != null) { + for (String slots : extraSection.getKeys(false)) { + BorderColor borderColor = BorderColor.valueOf(extraSection.getString(slots)); + try { + if (slots.contains("-")) { + String[] split = slots.split("-"); + int start = Integer.parseInt(split[0]); + int end = Integer.parseInt(split[1]); + for (int i = start; i <= end; i++) + extra.put(i, borderColor); } else { - colorData = inputParser.next(OrdinaryColor.class); - if (colorData == null) { - PlayerParticles.getInstance().getLogger().severe("Invalid color: '" + dataString + "'!"); - continue; - } + extra.put(Integer.parseInt(slots), borderColor); } - } else if (effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) { - if (effect == ParticleEffect.BLOCK || effect == ParticleEffect.FALLING_DUST) { - blockData = inputParser.next(Material.class); - if (blockData == null || !blockData.isBlock()) { - PlayerParticles.getInstance().getLogger().severe("Invalid block: '" + dataString + "'!"); - continue; - } - } else if (effect == ParticleEffect.ITEM) { - itemData = inputParser.next(Material.class); - if (itemData == null || itemData.isBlock()) { - PlayerParticles.getInstance().getLogger().severe("Invalid item: '" + dataString + "'!"); - continue; - } - } - } + } catch (NumberFormatException ignored) { } } - - particles.put(id, new ParticlePair(null, id, effect, style, itemData, blockData, colorData, noteColorData)); } - presets.add(new ParticleGroupPreset(HexUtils.colorify(displayName), guiIcon, guiSlot, permission, allowPermissionOverride, new ParticleGroup(groupName, particles))); + this.presetGroupPages.put(pageNumber++, new ParticleGroupPresetPage(title, presets, extra)); } - - Map extra = new HashMap<>(); - ConfigurationSection extraSection = pageSection.getConfigurationSection("extra"); - if (extraSection != null) { - for (String slots : extraSection.getKeys(false)) { - BorderColor borderColor = BorderColor.valueOf(extraSection.getString(slots)); - try { - if (slots.contains("-")) { - String[] split = slots.split("-"); - int start = Integer.parseInt(split[0]); - int end = Integer.parseInt(split[1]); - for (int i = start; i <= end; i++) - extra.put(i, borderColor); - } else { - extra.put(Integer.parseInt(slots), borderColor); - } - } catch (NumberFormatException ignored) { } - } - } - - this.presetGroupPages.put(pageNumber++, new ParticleGroupPresetPage(title, presets, extra)); + } catch (Exception ex) { + ex.printStackTrace(); + this.playerParticles.getLogger().severe("An error occurred while parsing the preset_groups.yml file!"); } } @@ -199,17 +212,46 @@ public class ParticleGroupPresetManager extends Manager { } /** - * @return a Map of page numbers to preset pages + * Gets a map of page numbers to preset pages for a PPlayer + * + * @param pplayer The PPlayer + * @return a Map of page numbers to preset pages for a PPlayer */ - public Map getPresetGroupPages() { - return Collections.unmodifiableMap(this.presetGroupPages); + public Map getPresetGroupPages(PPlayer pplayer) { + // Hide pages the player doesn't have access to anything for + Map presetGroupPages = new HashMap<>(); + + List pageNumbers = this.presetGroupPages.keySet().stream().sorted().collect(Collectors.toList()); + int pageNumber = 1; + for (int key : pageNumbers) { + ParticleGroupPresetPage page = this.presetGroupPages.get(key); + if (page.getPresets().stream().noneMatch(x -> x.canPlayerUse(pplayer))) + continue; + + presetGroupPages.put(pageNumber++, page); + } + + // Use a default page + if (presetGroupPages.isEmpty()) { + LocaleManager localeManager = this.playerParticles.getManager(LocaleManager.class); + Map extraBorder = new HashMap<>(); + IntStream.range(0, 9).forEach(x -> extraBorder.put(x, BorderColor.GREEN)); + IntStream.range(45, 54).forEach(x -> extraBorder.put(x, BorderColor.GREEN)); + Arrays.asList(9, 18, 27, 36, 17, 26, 35, 44).forEach(x -> extraBorder.put(x, BorderColor.GREEN)); + presetGroupPages.put(1, new ParticleGroupPresetPage(localeManager.getLocaleMessage("gui-load-a-preset-group"), Collections.emptyList(), extraBorder)); + } + + return Collections.unmodifiableMap(presetGroupPages); } /** - * @return the max page number for the preset groups + * Gets the max page number for preset groups for a PPlayer + * + * @param pplayer The PPlayer + * @return the max page number for the preset groups for a PPlayer */ - public int getMaxPageNumber() { - return this.presetGroupPages.keySet().stream() + public int getMaxPageNumber(PPlayer pplayer) { + return this.getPresetGroupPages(pplayer).keySet().stream() .mapToInt(Integer::intValue) .max() .orElse(1); @@ -218,7 +260,7 @@ public class ParticleGroupPresetManager extends Manager { /** * Gets all the preset ParticleGroups that a player can use * - * @param player The player + * @param player The PPlayer * @return a List of preset ParticleGroups the player can use */ public List getPresetGroupsForPlayer(PPlayer player) { @@ -251,4 +293,124 @@ public class ParticleGroupPresetManager extends Manager { return allPresets; } + private void tryMigrateOld(File presetsFile) { + CommentedFileConfiguration presetsConfig = CommentedFileConfiguration.loadConfiguration(this.playerParticles, presetsFile); + + // Check all keys to see if we have any that match both "presets" and "extra", that should be good enough + boolean title = false; + boolean extras = false; + boolean presets = false; + for (String key : presetsConfig.getKeys(true)) { + if (!title && key.contains("title")) + title = true; + if (!extras && key.contains("extra")) + extras = true; + if (!presets && key.contains("presets")) + presets = true; + } + + if (title && extras && presets) + return; + + // Convert existing preset_groups.yml into the new format + List existingPresets = new ArrayList<>(); + for (String groupName : presetsConfig.getKeys(false)) { + CommentedConfigurationSection groupSection = presetsConfig.getConfigurationSection(groupName); + String displayName = groupSection.getString("display-name"); + String guiIcon = groupSection.getString("gui-icon"); + String permission = groupSection.getString("permission"); + boolean allowPermissionOverride = groupSection.getBoolean("allow-permission-override"); + List particleData = new ArrayList<>(); + for (String key : groupSection.getKeys(false)) { + try { + int id = Integer.parseInt(key); + CommentedConfigurationSection particleGroup = groupSection.getConfigurationSection(key); + String effect = particleGroup.getString("effect"); + String style = particleGroup.getString("style"); + String data = particleGroup.getString("data"); + particleData.add(new ParticleData(id, effect, style, data)); + } catch (NumberFormatException ignored) { } + } + existingPresets.add(new PresetData(groupName, displayName, guiIcon, permission, allowPermissionOverride, particleData)); + } + + // Delete existing file, going to overwrite it all + presetsFile.delete(); + + // Copy over the new file + try (InputStream inStream = PlayerParticles.getInstance().getResource(ParticleGroupPresetManager.FILE_NAME)) { + Files.copy(inStream, Paths.get(presetsFile.getAbsolutePath())); + } catch (IOException e) { + e.printStackTrace(); + } + + // Reload the config + presetsConfig.reloadConfig(); + + // Delete everything in the presets section + presetsConfig.set("page1.presets", null); + + // Recreate presets section + CommentedConfigurationSection presetsSection = presetsConfig.createSection("page1.presets"); + + // Fill the data back in + int slot = 10; + int nextWrap = 17; + int maxSlot = 43; + + for (PresetData presetData : existingPresets) { + CommentedConfigurationSection presetSection = presetsSection.createSection(presetData.groupName); + presetSection.set("display-name", presetData.displayName); + presetSection.set("gui-icon", presetData.guiIcon); + presetSection.set("gui-slot", slot); + presetSection.set("permission", presetData.permission); + presetSection.set("allow-permission-override", presetData.allowPermissionOverride); + + for (ParticleData particleData : presetData.particleData) { + CommentedConfigurationSection particleSection = presetSection.createSection(String.valueOf(particleData.id)); + particleSection.set("effect", particleData.effect); + particleSection.set("style", particleData.style); + particleSection.set("data", particleData.data); + } + + slot++; + if (slot == nextWrap) { // Loop around border + nextWrap += 9; + slot += 2; + } + // Overflowed the available space + if (slot > maxSlot) + slot = maxSlot; + } + + presetsConfig.save(); + } + + private static class PresetData { + private final String groupName, displayName, guiIcon, permission; + private final boolean allowPermissionOverride; + private final List particleData; + + private PresetData(String groupName, String displayName, String guiIcon, String permission, boolean allowPermissionOverride, List particleData) { + this.groupName = groupName; + this.displayName = displayName; + this.guiIcon = guiIcon; + this.permission = permission; + this.allowPermissionOverride = allowPermissionOverride; + this.particleData = particleData; + } + } + + private static class ParticleData { + private final int id; + private final String effect, style, data; + + private ParticleData(int id, String effect, String style, String data) { + this.id = id; + this.effect = effect; + this.style = style; + this.data = data; + } + } + } diff --git a/src/main/java/dev/esophose/playerparticles/manager/ParticleManager.java b/src/main/java/dev/esophose/playerparticles/manager/ParticleManager.java index 2c98b84..f23e128 100644 --- a/src/main/java/dev/esophose/playerparticles/manager/ParticleManager.java +++ b/src/main/java/dev/esophose/playerparticles/manager/ParticleManager.java @@ -53,7 +53,6 @@ public class ParticleManager extends Manager implements Listener, Runnable { * Rainbow particle effect hue and note color used for rainbow colorable effects */ private int hue; - private int note; private final Random random; public ParticleManager(PlayerParticles playerParticles) { @@ -62,7 +61,6 @@ public class ParticleManager extends Manager implements Listener, Runnable { this.particlePlayers = new ConcurrentHashMap<>(); this.particleTask = null; this.hue = 0; - this.note = 0; this.random = new Random(); Bukkit.getPluginManager().registerEvents(this, this.playerParticles); @@ -155,11 +153,6 @@ public class ParticleManager extends Manager implements Listener, Runnable { this.hue += Setting.RAINBOW_CYCLE_SPEED.getInt(); this.hue %= 360; - if (this.hue % 4 == 0) { // Only increment note by 5 notes per second - this.note++; - this.note %= 25; - } - PermissionManager permissionManager = this.playerParticles.getManager(PermissionManager.class); // Spawn particles for each player @@ -295,7 +288,8 @@ public class ParticleManager extends Manager implements Listener, Runnable { * @return The rainbow NoteColor for particle spawning with data 'rainbow' */ public NoteColor getRainbowNoteParticleColor() { - return new NoteColor(this.note); + int note = ((int) Math.round(24 - 24 / 360.0 * this.hue) + 7) % 24; + return new NoteColor(note); } /**