SongodaCore/Core/src/main/java/com/songoda/core/configuration/editor/ConfigEditorGui.java

341 lines
14 KiB
Java

package com.songoda.core.configuration.editor;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.Gui;
import com.songoda.core.gui.GuiUtils;
import com.songoda.core.gui.SimplePagedGui;
import com.songoda.core.input.ChatPrompt;
import com.songoda.core.utils.ItemUtils;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemoryConfiguration;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
/**
* Edit a configuration file for a specific plugin
*
* @deprecated Needs a recode in another package
*/
@Deprecated
public class ConfigEditorGui extends SimplePagedGui {
final JavaPlugin plugin;
final String file;
final MemoryConfiguration config;
final ConfigurationSection node;
final Player player;
Method configSection_getCommentString = null;
boolean edits = false;
List<String> sections = new ArrayList<>();
List<String> settings = new ArrayList<>();
protected ConfigEditorGui(Player player, JavaPlugin plugin, Gui parent, String file, MemoryConfiguration config) {
this(player, plugin, parent, file, config, config);
}
protected ConfigEditorGui(Player player, JavaPlugin plugin, Gui parent, String file, MemoryConfiguration config, ConfigurationSection node) {
super(parent);
this.player = player;
this.plugin = plugin;
this.file = file;
this.config = config;
this.node = node;
this.blankItem = GuiUtils.getBorderItem(CompatibleMaterial.LIGHT_GRAY_STAINED_GLASS_PANE);
if (!(parent instanceof ConfigEditorGui)) {
setOnClose((gui) -> save());
} else {
setOnClose((gui) -> ((ConfigEditorGui) parent).edits |= edits);
}
// if we have a ConfigSection, we can also grab comments
try {
configSection_getCommentString = node.getClass().getDeclaredMethod("getCommentString", String.class);
} catch (Exception ignore) {
}
// decorate header
this.setTitle(ChatColor.DARK_BLUE + file);
this.setUseHeader(true);
headerBackItem = footerBackItem = GuiUtils.getBorderItem(CompatibleMaterial.GRAY_STAINED_GLASS_PANE.getItem());
final String path = node.getCurrentPath();
this.setItem(4, configItem(CompatibleMaterial.FILLED_MAP, !path.isEmpty() ? path : file, config, !path.isEmpty() ? path : null, ChatColor.BLACK.toString()));
this.setButton(8, GuiUtils.createButtonItem(CompatibleMaterial.OAK_DOOR, "Exit"), (event) -> event.player.closeInventory());
// compile list of settings
for (String key : node.getKeys(false)) {
if (node.isConfigurationSection(key)) {
sections.add(key);
continue;
}
settings.add(key);
}
// next we need to display the config settings
int index = 9;
for (final String sectionKey : sections) {
setButton(index++, configItem(CompatibleMaterial.WRITABLE_BOOK, ChatColor.YELLOW + sectionKey, node, sectionKey, "Click to open this section"),
(event) -> event.manager.showGUI(event.player, new ConfigEditorGui(player, plugin, this, file, config, node.getConfigurationSection(sectionKey))));
}
// now display individual settings
for (final String settingKey : settings) {
final Object val = node.get(settingKey);
if (val == null) {
continue;
}
if (val instanceof Boolean) {
// toggle switch
setButton(index, configItem(CompatibleMaterial.LEVER, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf(val), "Click to toggle this setting"),
(event) -> this.toggle(event.slot, settingKey));
if ((Boolean) val) {
highlightItem(index);
}
} else if (isNumber(val)) {
// number dial
this.setButton(index, configItem(CompatibleMaterial.CLOCK, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf(val), "Click to edit this setting"),
(event) -> {
event.gui.exit();
ChatPrompt.showPrompt(plugin, event.player, "Enter a new number value for " + settingKey + ":", response -> {
if (!setNumber(event.slot, settingKey, response.getMessage().trim())) {
event.player.sendMessage(ChatColor.RED + "Error: \"" + response.getMessage().trim() + "\" is not a number!");
}
}).setOnClose(() -> event.manager.showGUI(event.player, this))
.setOnCancel(() -> {
event.player.sendMessage(ChatColor.RED + "Edit canceled");
event.manager.showGUI(event.player, this);
});
});
} else if (isMaterial(val)) {
// changing a block
// isMaterial is more of a guess, to be honest.
setButton(index, configItem(CompatibleMaterial.STONE, ChatColor.YELLOW + settingKey, node, settingKey, val.toString(), "Click to edit this setting"),
(event) -> {
SimplePagedGui paged = new SimplePagedGui(this);
paged.setTitle(ChatColor.BLUE + settingKey);
paged.setHeaderBackItem(headerBackItem).setFooterBackItem(footerBackItem).setDefaultItem(blankItem);
paged.setItem(4, configItem(CompatibleMaterial.FILLED_MAP, settingKey, node, settingKey, "Choose an item to change this value to"));
int i = 9;
for (CompatibleMaterial mat : CompatibleMaterial.getAllValidItemMaterials()) {
try {
ItemStack buttonItem = GuiUtils.createButtonItem(mat, mat.name());
if (!buttonItem.getType().isItem()) continue;
paged.setButton(i++, buttonItem, ClickType.LEFT, (matEvent) -> {
setMaterial(event.slot, settingKey, matEvent.clickedItem);
matEvent.player.closeInventory();
});
} catch (IllegalArgumentException ex) {
// FIXME: CompatibleMaterial is not working properly for 'ZOMBIE_PIGMAN_SPAWN_EGG'
}
}
event.manager.showGUI(event.player, paged);
});
} else if (val instanceof String) {
// changing a "string" value (or change to a feather for writing quill)
setButton(index, configItem(CompatibleMaterial.STRING, ChatColor.YELLOW + settingKey, node, settingKey, val.toString(), "Click to edit this setting"),
(event) -> {
event.gui.exit();
ChatPrompt.showPrompt(plugin, event.player, "Enter a new value for " + settingKey + ":", response -> {
node.set(settingKey, response.getMessage().trim());
updateValue(event.slot, settingKey);
}).setOnClose(() -> event.manager.showGUI(event.player, this))
.setOnCancel(() -> {
event.player.sendMessage(ChatColor.RED + "Edit canceled");
event.manager.showGUI(event.player, this);
});
});
} else if (val instanceof List) {
setButton(index, configItem(CompatibleMaterial.WRITABLE_BOOK, ChatColor.YELLOW + settingKey, node, settingKey, String.format("(%d values)", ((List<?>) val).size()), "Click to edit this setting"),
(event) ->
event.manager.showGUI(event.player, (new ConfigEditorListEditorGui(this, settingKey, (List) val)).setOnClose((gui) -> {
if (((ConfigEditorListEditorGui) gui.gui).saveChanges) {
setList(event.slot, settingKey, ((ConfigEditorListEditorGui) gui.gui).values);
}
})));
} /* else {
// idk. should we display uneditable values?
} */
++index;
}
}
public ConfigurationSection getCurrentNode() {
return node;
}
protected void updateValue(int clickCell, String path) {
ItemStack item = inventory.getItem(clickCell);
if (item == null || item == AIR) {
return;
}
ItemMeta meta = item.getItemMeta();
Object val = node.get(path);
if (meta != null && val != null) {
String valStr;
if (val instanceof List) {
valStr = String.format("(%d values)", ((List<?>) val).size());
} else {
valStr = val.toString();
}
List<String> lore = meta.getLore();
if (lore == null || lore.isEmpty()) {
meta.setLore(Arrays.asList(valStr));
} else {
lore.set(0, valStr);
meta.setLore(lore);
}
item.setItemMeta(meta);
setItem(clickCell, item);
}
edits = true;
}
void toggle(int clickCell, String path) {
boolean val = !node.getBoolean(path);
node.set(path, val);
if (val) {
setItem(clickCell, ItemUtils.addGlow(inventory.getItem(clickCell)));
} else {
setItem(clickCell, ItemUtils.removeGlow(inventory.getItem(clickCell)));
}
updateValue(clickCell, path);
}
boolean setNumber(int clickCell, String path, String input) {
try {
if (node.isInt(path)) {
node.set(path, Integer.parseInt(input));
} else if (node.isDouble(path)) {
node.set(path, Double.parseDouble(input));
} else if (node.isLong(path)) {
node.set(path, Long.parseLong(input));
}
updateValue(clickCell, path);
} catch (NumberFormatException ex) {
return false;
}
return true;
}
void setMaterial(int clickCell, String path, ItemStack item) {
CompatibleMaterial mat = CompatibleMaterial.getMaterial(item);
if (mat == null) {
node.set(path, CompatibleMaterial.STONE.name());
} else {
node.set(path, mat.name());
}
updateValue(clickCell, path);
}
void setList(int clickCell, String path, List<String> list) {
node.set(path, list);
updateValue(clickCell, path);
}
void save() {
if (!edits) {
return;
}
// could also check and call saveChanges()
if (config instanceof FileConfiguration) {
try {
((FileConfiguration) config).save(new File(plugin.getDataFolder(), file));
} catch (IOException ex) {
plugin.getLogger().log(Level.SEVERE, "Failed to save config changes to " + file, ex);
return;
}
}/* else if (config instanceof Config) {
((Config) config).save();
}*/ else {
player.sendMessage(ChatColor.RED + "Unknown configuration type '" + config.getClass().getName() + "' - Please report this error!");
plugin.getLogger().log(Level.WARNING, "Unknown configuration type '" + config.getClass().getName() + "' - Please report this error!");
return;
}
plugin.reloadConfig();
player.sendMessage(ChatColor.GREEN + "Config " + file + " saved!");
}
private boolean isNumber(Object value) {
return (value instanceof Long
|| value instanceof Integer
|| value instanceof Float
|| value instanceof Double);
}
private boolean isMaterial(Object value) {
CompatibleMaterial m;
return value instanceof String && value.toString().equals(value.toString().toUpperCase())
&& (m = CompatibleMaterial.getMaterial(value.toString())) != null && m.isValidItem();
}
protected ItemStack configItem(CompatibleMaterial type, String name, ConfigurationSection node, String path, String def) {
String[] info = null;
if (configSection_getCommentString != null) {
try {
Object comment = configSection_getCommentString.invoke(node, path);
if (comment != null) {
info = comment.toString().split("\n");
}
} catch (Exception ignore) {
}
}
return GuiUtils.createButtonItem(type, name, info != null ? info : (def != null ? def.split("\n") : null));
}
protected ItemStack configItem(CompatibleMaterial type, String name, ConfigurationSection node, String path, String value, String def) {
if (value == null) {
value = "";
}
String[] info = null;
if (configSection_getCommentString != null) {
try {
Object comment = configSection_getCommentString.invoke(node, path);
if (comment != null) {
info = (value + "\n" + comment).split("\n");
}
} catch (Exception ignore) {
}
}
return GuiUtils.createButtonItem(type, name, info != null ? info : (def != null ? (value + "\n" + def).split("\n") : null));
}
}