Hide GUI preset pages if there's nothing on them

This commit is contained in:
Esophose 2020-09-17 21:39:07 -06:00
parent 00848211cf
commit 99daf94112
15 changed files with 336 additions and 288 deletions

View file

@ -12,7 +12,7 @@ public class DefaultCommandModule implements CommandModule {
public void onCommandExecute(PPlayer pplayer, String[] args) { public void onCommandExecute(PPlayer pplayer, String[] args) {
// The default command just opens the GUI, execute the GUICommandModule // The default command just opens the GUI, execute the GUICommandModule
((GUICommandModule) PlayerParticles.getInstance().getManager(CommandManager.class).findMatchingCommand("gui")) ((GUICommandModule) PlayerParticles.getInstance().getManager(CommandManager.class).findMatchingCommand("gui"))
.onCommandExecute(pplayer, false); .onCommandExecute(pplayer, new String[0], false);
} }
public List<String> onTabComplete(PPlayer pplayer, String[] args) { public List<String> onTabComplete(PPlayer pplayer, String[] args) {

View file

@ -7,16 +7,17 @@ import dev.esophose.playerparticles.manager.LocaleManager;
import dev.esophose.playerparticles.manager.PermissionManager; import dev.esophose.playerparticles.manager.PermissionManager;
import dev.esophose.playerparticles.particles.PPlayer; import dev.esophose.playerparticles.particles.PPlayer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.bukkit.Bukkit; import org.bukkit.util.StringUtil;
public class GUICommandModule implements CommandModule { public class GUICommandModule implements CommandModule {
public void onCommandExecute(PPlayer pplayer, String[] args) { 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); PermissionManager permissionManager = PlayerParticles.getInstance().getManager(PermissionManager.class);
LocaleManager localeManager = PlayerParticles.getInstance().getManager(LocaleManager.class); LocaleManager localeManager = PlayerParticles.getInstance().getManager(LocaleManager.class);
GuiManager guiManager = PlayerParticles.getInstance().getManager(GuiManager.class); GuiManager guiManager = PlayerParticles.getInstance().getManager(GuiManager.class);
@ -45,11 +46,20 @@ public class GUICommandModule implements CommandModule {
return; 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<String> onTabComplete(PPlayer pplayer, String[] args) { public List<String> onTabComplete(PPlayer pplayer, String[] args) {
return new ArrayList<>(); List<String> completions = new ArrayList<>();
if (args.length == 1) {
List<String> possibilities = Collections.singletonList("presets");
StringUtil.copyPartialMatches(args[0], possibilities, completions);
}
return completions;
} }
public String getName() { public String getName() {

View file

@ -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<PresetData> 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> 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> particleData;
private PresetData(String groupName, String displayName, String guiIcon, String permission, boolean allowPermissionOverride, List<ParticleData> 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;
}
}
}

View file

@ -152,7 +152,7 @@ public class GuiInventoryEditData extends GuiInventory {
if (pe == ParticleEffect.NOTE) { // Note data if (pe == ParticleEffect.NOTE) { // Note data
this.populateNoteData(editingParticle, pageNumber, callbackList, callbackListPosition); this.populateNoteData(editingParticle, pageNumber, callbackList, callbackListPosition);
} else { // Color data } else { // Color data
this.populateColorData(editingParticle, pageNumber, callbackList, callbackListPosition); this.populateColorData(editingParticle, callbackList, callbackListPosition);
} }
} else if (pe.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) { } else if (pe.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
if (pe == ParticleEffect.ITEM) { // Item data if (pe == ParticleEffect.ITEM) { // Item data
@ -178,11 +178,10 @@ public class GuiInventoryEditData extends GuiInventory {
* Populates the Inventory with available color data options * Populates the Inventory with available color data options
* *
* @param editingParticle The ParticlePair that's being edited * @param editingParticle The ParticlePair that's being edited
* @param pageNumber The current page number
* @param callbackList The List of GuiInventoryEditFinishedCallbacks * @param callbackList The List of GuiInventoryEditFinishedCallbacks
* @param callbackListPosition The index of the callbackList we're currently at * @param callbackListPosition The index of the callbackList we're currently at
*/ */
private void populateColorData(ParticlePair editingParticle, int pageNumber, List<Runnable> callbackList, int callbackListPosition) { private void populateColorData(ParticlePair editingParticle, List<Runnable> callbackList, int callbackListPosition) {
LocaleManager localeManager = PlayerParticles.getInstance().getManager(LocaleManager.class); LocaleManager localeManager = PlayerParticles.getInstance().getManager(LocaleManager.class);
int index = 10; int index = 10;

View file

@ -23,7 +23,7 @@ import org.bukkit.Bukkit;
public class GuiInventoryLoadPresetGroups extends GuiInventory { public class GuiInventoryLoadPresetGroups extends GuiInventory {
public GuiInventoryLoadPresetGroups(PPlayer pplayer, boolean isEndPoint, int pageNumber) { 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(); PlayerParticles playerParticles = PlayerParticles.getInstance();
ParticleGroupPresetManager presetManager = playerParticles.getManager(ParticleGroupPresetManager.class); ParticleGroupPresetManager presetManager = playerParticles.getManager(ParticleGroupPresetManager.class);
@ -32,11 +32,10 @@ public class GuiInventoryLoadPresetGroups extends GuiInventory {
this.fillBorder(BorderColor.GREEN); this.fillBorder(BorderColor.GREEN);
ParticleGroupPresetPage pageInfo = presetManager.getPresetGroupPages().get(pageNumber); ParticleGroupPresetPage pageInfo = presetManager.getPresetGroupPages(pplayer).get(pageNumber);
List<ParticleGroupPreset> groups = pageInfo.getPresets();
Map<Integer, BorderColor> extraBorder = pageInfo.getExtraBorder(); Map<Integer, BorderColor> extraBorder = pageInfo.getExtraBorder();
int maxPages = presetManager.getMaxPageNumber(); int maxPages = presetManager.getMaxPageNumber(pplayer);
// Fill borders // Fill borders
extraBorder.forEach((item, color) -> this.inventory.setItem(item, color.getIcon())); extraBorder.forEach((item, color) -> this.inventory.setItem(item, color.getIcon()));

View file

@ -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("gui-manage-your-groups-description", "Create, delete, and load your particle groups");
this.put("#31", "GUI Load Messages"); 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("gui-load-a-preset-group-description", "Load a premade particle group");
this.put("#32", "GUI Save Messages"); this.put("#32", "GUI Save Messages");

View file

@ -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("gui-manage-your-groups-description", "Créez, éditez, et supprimez vos groupes particules");
this.put("#31", "GUI Load Messages"); 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("gui-load-a-preset-group-description", "Chargez un groupe de particules déjà fait");
this.put("#32", "GUI Save Messages"); this.put("#32", "GUI Save Messages");

View file

@ -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("gui-manage-your-groups-description", "Erstellen, löschen und laden Sie Ihre Partikelgruppen");
this.put("#31", "GUI Load Messages"); 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("gui-load-a-preset-group-description", "Laden Sie eine vorgefertigte Partikelgruppe");
this.put("#32", "GUI Save Messages"); this.put("#32", "GUI Save Messages");

View file

@ -276,6 +276,7 @@ public class RussianLocale implements Locale {
this.put("gui-manage-your-groups-description", "Создание, изменение и удаление Ваших групп"); this.put("gui-manage-your-groups-description", "Создание, изменение и удаление Ваших групп");
this.put("#31", "GUI Load Messages"); this.put("#31", "GUI Load Messages");
this.put("gui-load-a-preset-group", "Установить группу");
this.put("gui-load-a-preset-group-description", "Установка готовой группы частиц"); this.put("gui-load-a-preset-group-description", "Установка готовой группы частиц");
this.put("#32", "GUI Save Messages"); this.put("#32", "GUI Save Messages");

View file

@ -276,6 +276,7 @@ public class SimplifiedChineseLocale implements Locale {
this.put("gui-manage-your-groups-description", "创建、删除和加载你的粒子组"); this.put("gui-manage-your-groups-description", "创建、删除和加载你的粒子组");
this.put("#31", "GUI Load Messages"); this.put("#31", "GUI Load Messages");
this.put("gui-load-a-preset-group", "加载预设粒子组");
this.put("gui-load-a-preset-group-description", "加载预设粒子组"); this.put("gui-load-a-preset-group-description", "加载预设粒子组");
this.put("#32", "GUI Save Messages"); this.put("#32", "GUI Save Messages");

View file

@ -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("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("#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("gui-load-a-preset-group-description", "Tải Group Hạt hiệu ứng có sẵn");
this.put("#32", "GUI Save Messages"); this.put("#32", "GUI Save Messages");

View file

@ -5,7 +5,6 @@ import dev.esophose.playerparticles.database.DataMigration;
import dev.esophose.playerparticles.database.DatabaseConnector; import dev.esophose.playerparticles.database.DatabaseConnector;
import dev.esophose.playerparticles.database.SQLiteConnector; import dev.esophose.playerparticles.database.SQLiteConnector;
import dev.esophose.playerparticles.database.migrations._1_InitialMigration; import dev.esophose.playerparticles.database.migrations._1_InitialMigration;
import dev.esophose.playerparticles.database.migrations._2_PresetGroupsGuiSections;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.Arrays; import java.util.Arrays;
@ -21,8 +20,7 @@ public class DataMigrationManager extends Manager {
super(playerParticles); super(playerParticles);
this.migrations = Arrays.asList( this.migrations = Arrays.asList(
new _1_InitialMigration(), new _1_InitialMigration()
new _2_PresetGroupsGuiSections(this.playerParticles)
); );
} }

View file

@ -109,17 +109,34 @@ public class GuiManager extends Manager implements Listener, Runnable {
* @param pplayer The PPlayer to open the GUI screen for * @param pplayer The PPlayer to open the GUI screen for
*/ */
public void openDefault(PPlayer pplayer) { public void openDefault(PPlayer pplayer) {
Bukkit.getScheduler().runTask(this.playerParticles, () -> { if (Setting.GUI_PRESETS_ONLY.getBoolean()) {
GuiInventory inventoryToOpen; this.openPresetGroups(pplayer);
if (!Setting.GUI_PRESETS_ONLY.getBoolean()) { return;
inventoryToOpen = new GuiInventoryDefault(pplayer); }
} else {
inventoryToOpen = new GuiInventoryLoadPresetGroups(pplayer, true, 1);
}
pplayer.getPlayer().openInventory(inventoryToOpen.getInventory()); Bukkit.getScheduler().runTask(this.playerParticles, () ->
this.guiInventories.add(inventoryToOpen); 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);
} }
/** /**

View file

@ -1,6 +1,8 @@
package dev.esophose.playerparticles.manager; package dev.esophose.playerparticles.manager;
import dev.esophose.playerparticles.PlayerParticles; 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.gui.GuiInventory.BorderColor;
import dev.esophose.playerparticles.particles.PPlayer; import dev.esophose.playerparticles.particles.PPlayer;
import dev.esophose.playerparticles.particles.ParticleEffect; import dev.esophose.playerparticles.particles.ParticleEffect;
@ -20,6 +22,7 @@ import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
@ -27,6 +30,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
@ -52,144 +56,153 @@ public class ParticleGroupPresetManager extends Manager {
if (!pluginDataFolder.exists()) if (!pluginDataFolder.exists())
pluginDataFolder.mkdir(); pluginDataFolder.mkdir();
File groupsFile = new File(pluginDataFolder, FILE_NAME); File presetsFile = new File(pluginDataFolder, FILE_NAME);
// Create the file if it doesn't exist // Create the file if it doesn't exist
if (!groupsFile.exists()) { if (!presetsFile.exists()) {
try (InputStream inStream = PlayerParticles.getInstance().getResource(FILE_NAME)) { 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) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} else {
this.tryMigrateOld(presetsFile);
} }
// Parse groups.yml file // Parse groups.yml file
YamlConfiguration groupsYaml = YamlConfiguration.loadConfiguration(groupsFile); try {
int pageNumber = 1; YamlConfiguration groupsYaml = YamlConfiguration.loadConfiguration(presetsFile);
for (String pageKey: groupsYaml.getKeys(false)) { int pageNumber = 1;
ConfigurationSection pageSection = groupsYaml.getConfigurationSection(pageKey); for (String pageKey: groupsYaml.getKeys(false)) {
String title = HexUtils.colorify(pageSection.getString("title")); ConfigurationSection pageSection = groupsYaml.getConfigurationSection(pageKey);
ConfigurationSection presetsSection = pageSection.getConfigurationSection("presets"); String title = HexUtils.colorify(pageSection.getString("title"));
List<ParticleGroupPreset> presets = new ArrayList<>(); ConfigurationSection presetsSection = pageSection.getConfigurationSection("presets");
for (String groupName : presetsSection.getKeys(false)) { List<ParticleGroupPreset> presets = new ArrayList<>();
Map<Integer, ParticlePair> particles = new HashMap<>(); if (presetsSection != null) {
String displayName = ""; for (String groupName : presetsSection.getKeys(false)) {
Material guiIcon = Material.ENDER_CHEST; Map<Integer, ParticlePair> particles = new HashMap<>();
int guiSlot = -1; String displayName = "";
String permission = ""; Material guiIcon = Material.ENDER_CHEST;
boolean allowPermissionOverride = false; int guiSlot = -1;
ConfigurationSection groupSection = presetsSection.getConfigurationSection(groupName); String permission = "";
boolean allowPermissionOverride = false;
ConfigurationSection groupSection = presetsSection.getConfigurationSection(groupName);
Set<String> particleKeys = groupSection.getKeys(false); Set<String> particleKeys = groupSection.getKeys(false);
for (String stringId : particleKeys) { for (String stringId : particleKeys) {
if (stringId.equalsIgnoreCase("display-name")) { if (stringId.equalsIgnoreCase("display-name")) {
displayName = groupSection.getString(stringId); displayName = groupSection.getString(stringId);
continue; continue;
} }
if (stringId.equalsIgnoreCase("gui-icon")) { if (stringId.equalsIgnoreCase("gui-icon")) {
guiIcon = Material.matchMaterial(groupSection.getString(stringId)); guiIcon = Material.matchMaterial(groupSection.getString(stringId));
continue; continue;
} }
if (stringId.equalsIgnoreCase("gui-slot")) { if (stringId.equalsIgnoreCase("gui-slot")) {
guiSlot = groupSection.getInt(stringId); guiSlot = groupSection.getInt(stringId);
continue; continue;
} }
if (stringId.equalsIgnoreCase("permission")) { if (stringId.equalsIgnoreCase("permission")) {
permission = groupSection.getString(stringId); permission = groupSection.getString(stringId);
continue; continue;
} }
if (stringId.equalsIgnoreCase("allow-permission-override")) { if (stringId.equalsIgnoreCase("allow-permission-override")) {
allowPermissionOverride = groupSection.getBoolean(stringId); allowPermissionOverride = groupSection.getBoolean(stringId);
continue; continue;
} }
ConfigurationSection particleSection = groupSection.getConfigurationSection(stringId); ConfigurationSection particleSection = groupSection.getConfigurationSection(stringId);
int id = Integer.parseInt(stringId); int id = Integer.parseInt(stringId);
ParticleEffect effect = new InputParser(null, new String[] { particleSection.getString("effect") }).next(ParticleEffect.class); 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); ParticleStyle style = new InputParser(null, new String[] { particleSection.getString("style") }).next(ParticleStyle.class);
if (effect == null) { if (effect == null) {
PlayerParticles.getInstance().getLogger().severe("Invalid effect name: '" + particleSection.getString("effect") + "'!"); PlayerParticles.getInstance().getLogger().severe("Invalid effect name: '" + particleSection.getString("effect") + "'!");
continue; continue;
} }
if (style == null) { if (style == null) {
PlayerParticles.getInstance().getLogger().severe("Invalid style name: '" + particleSection.getString("style") + "'!"); PlayerParticles.getInstance().getLogger().severe("Invalid style name: '" + particleSection.getString("style") + "'!");
continue; continue;
} }
Material itemData = null; Material itemData = null;
Material blockData = null; Material blockData = null;
OrdinaryColor colorData = null; OrdinaryColor colorData = null;
NoteColor noteColorData = null; NoteColor noteColorData = null;
String dataString = particleSection.getString("data"); String dataString = particleSection.getString("data");
if (dataString != null && !dataString.isEmpty()) { if (dataString != null && !dataString.isEmpty()) {
String[] args = dataString.split(" "); String[] args = dataString.split(" ");
InputParser inputParser = new InputParser(null, args); InputParser inputParser = new InputParser(null, args);
if (effect.hasProperty(ParticleProperty.COLORABLE)) { if (effect.hasProperty(ParticleProperty.COLORABLE)) {
if (effect == ParticleEffect.NOTE) { if (effect == ParticleEffect.NOTE) {
noteColorData = inputParser.next(NoteColor.class); noteColorData = inputParser.next(NoteColor.class);
if (noteColorData == null) { if (noteColorData == null) {
PlayerParticles.getInstance().getLogger().severe("Invalid note: '" + dataString + "'!"); PlayerParticles.getInstance().getLogger().severe("Invalid note: '" + dataString + "'!");
continue; 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<Integer, BorderColor> 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 { } else {
colorData = inputParser.next(OrdinaryColor.class); extra.put(Integer.parseInt(slots), borderColor);
if (colorData == null) {
PlayerParticles.getInstance().getLogger().severe("Invalid color: '" + dataString + "'!");
continue;
}
} }
} else if (effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) { } catch (NumberFormatException ignored) { }
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))); this.presetGroupPages.put(pageNumber++, new ParticleGroupPresetPage(title, presets, extra));
} }
} catch (Exception ex) {
Map<Integer, BorderColor> extra = new HashMap<>(); ex.printStackTrace();
ConfigurationSection extraSection = pageSection.getConfigurationSection("extra"); this.playerParticles.getLogger().severe("An error occurred while parsing the preset_groups.yml file!");
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));
} }
} }
@ -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<Integer, ParticleGroupPresetPage> getPresetGroupPages() { public Map<Integer, ParticleGroupPresetPage> getPresetGroupPages(PPlayer pplayer) {
return Collections.unmodifiableMap(this.presetGroupPages); // Hide pages the player doesn't have access to anything for
Map<Integer, ParticleGroupPresetPage> presetGroupPages = new HashMap<>();
List<Integer> 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<Integer, BorderColor> 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() { public int getMaxPageNumber(PPlayer pplayer) {
return this.presetGroupPages.keySet().stream() return this.getPresetGroupPages(pplayer).keySet().stream()
.mapToInt(Integer::intValue) .mapToInt(Integer::intValue)
.max() .max()
.orElse(1); .orElse(1);
@ -218,7 +260,7 @@ public class ParticleGroupPresetManager extends Manager {
/** /**
* Gets all the preset ParticleGroups that a player can use * 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 * @return a List of preset ParticleGroups the player can use
*/ */
public List<ParticleGroupPreset> getPresetGroupsForPlayer(PPlayer player) { public List<ParticleGroupPreset> getPresetGroupsForPlayer(PPlayer player) {
@ -251,4 +293,124 @@ public class ParticleGroupPresetManager extends Manager {
return allPresets; 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<PresetData> 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> 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> particleData;
private PresetData(String groupName, String displayName, String guiIcon, String permission, boolean allowPermissionOverride, List<ParticleData> 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;
}
}
} }

View file

@ -53,7 +53,6 @@ public class ParticleManager extends Manager implements Listener, Runnable {
* Rainbow particle effect hue and note color used for rainbow colorable effects * Rainbow particle effect hue and note color used for rainbow colorable effects
*/ */
private int hue; private int hue;
private int note;
private final Random random; private final Random random;
public ParticleManager(PlayerParticles playerParticles) { public ParticleManager(PlayerParticles playerParticles) {
@ -62,7 +61,6 @@ public class ParticleManager extends Manager implements Listener, Runnable {
this.particlePlayers = new ConcurrentHashMap<>(); this.particlePlayers = new ConcurrentHashMap<>();
this.particleTask = null; this.particleTask = null;
this.hue = 0; this.hue = 0;
this.note = 0;
this.random = new Random(); this.random = new Random();
Bukkit.getPluginManager().registerEvents(this, this.playerParticles); 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 += Setting.RAINBOW_CYCLE_SPEED.getInt();
this.hue %= 360; 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); PermissionManager permissionManager = this.playerParticles.getManager(PermissionManager.class);
// Spawn particles for each player // 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' * @return The rainbow NoteColor for particle spawning with data 'rainbow'
*/ */
public NoteColor getRainbowNoteParticleColor() { 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);
} }
/** /**