Common config editor

This commit is contained in:
jascotty2 2019-08-31 17:51:33 -05:00
parent 7f3ac8f5a2
commit 9ee17cc27e
9 changed files with 227 additions and 32 deletions

View File

@ -46,8 +46,8 @@ public class SongodaCore {
private static SongodaCore INSTANCE = null;
private JavaPlugin piggybackedPlugin;
private final CommandManager commandManager;
private final EventListener loginListener = new EventListener();
private final ShadedEventListener shadingListener = new ShadedEventListener();
private EventListener loginListener;
private ShadedEventListener shadingListener;
public static boolean hasShading() {
// sneaky hack to check the package name since maven tries to re-shade all references to the package string
@ -68,7 +68,9 @@ public class SongodaCore {
clazz.getMethod("registerPlugin", JavaPlugin.class, int.class, String.class).invoke(null, plugin, pluginID, icon);
if(hasShading()) {
Bukkit.getPluginManager().registerEvents(new ShadedEventListener(), plugin);
(INSTANCE = new SongodaCore()).piggybackedPlugin = plugin;
INSTANCE.shadingListener = new ShadedEventListener();
Bukkit.getPluginManager().registerEvents(INSTANCE.shadingListener, plugin);
}
return;
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) {
@ -77,23 +79,33 @@ public class SongodaCore {
}
// register ourselves as the SongodaCore service!
INSTANCE = new SongodaCore(plugin);
INSTANCE.init();
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, plugin, ServicePriority.Normal);
}
INSTANCE.register(plugin, pluginID, icon);
}
public SongodaCore(JavaPlugin javaPlugin) {
SongodaCore() {
commandManager = null;
}
SongodaCore(JavaPlugin javaPlugin) {
piggybackedPlugin = javaPlugin;
commandManager = new CommandManager(piggybackedPlugin);
loginListener = new EventListener();
shadingListener = new ShadedEventListener();
}
private void init() {
commandManager.registerCommandDynamically(new SongodaCoreCommand(this))
.addSubCommand(new SongodaCoreDiagCommand(this));
Bukkit.getPluginManager().registerEvents(loginListener, javaPlugin);
Bukkit.getPluginManager().registerEvents(shadingListener, javaPlugin);
Bukkit.getPluginManager().registerEvents(loginListener, piggybackedPlugin);
Bukkit.getPluginManager().registerEvents(shadingListener, piggybackedPlugin);
// we aggressevely want to own this command
Bukkit.getScheduler().runTaskLaterAsynchronously(javaPlugin, ()->{CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);}, 10 * 60 * 1);
Bukkit.getScheduler().runTaskLaterAsynchronously(javaPlugin, ()->{CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);}, 20 * 60 * 1);
Bukkit.getScheduler().runTaskLaterAsynchronously(javaPlugin, ()->{CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);}, 20 * 60 * 2);
Bukkit.getScheduler().runTaskLaterAsynchronously(javaPlugin, ()->registerAllPlugins(), 20 * 60 * 2);
Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, ()->{CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);}, 10 * 60 * 1);
Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, ()->{CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);}, 20 * 60 * 1);
Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, ()->{CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);}, 20 * 60 * 2);
Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, ()->registerAllPlugins(), 20 * 60 * 2);
}
/**

View File

@ -37,7 +37,6 @@ public class ClientVersion {
Bukkit.getScheduler().runTaskLater(SongodaCore.getHijackedPlugin(), ()-> {
if(p.isOnline()) {
final int version = protocolsupport.api.ProtocolSupportAPI.getProtocolVersion(p).getId();
System.out.println("ProtoLogin" + version);
players.put(p.getUniqueId(), protocolToVersion(version));
}
}, 20);
@ -51,7 +50,6 @@ public class ClientVersion {
Bukkit.getScheduler().runTaskLater(SongodaCore.getHijackedPlugin(), ()-> {
if(p.isOnline()) {
final int version = us.myles.ViaVersion.api.Via.getAPI().getPlayerVersion(p.getUniqueId());
System.out.println("ViaLogin" + version);
players.put(p.getUniqueId(), protocolToVersion(version));
}
}, 20);

View File

@ -818,7 +818,7 @@ public enum CompatibleSounds {
protected /*final*/ Sound sound;
protected /*final*/ boolean compatibilityMode;
protected static final boolean DEBUG = true;
protected static final boolean DEBUG = false;
private CompatibleSounds() {
// This could get risky, since we haven't finished this

View File

@ -6,6 +6,7 @@ import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* A comment for a configuration key
@ -51,6 +52,11 @@ public class Comment {
return lines;
}
@Override
public String toString() {
return lines.isEmpty() ? "" : lines.stream().collect(Collectors.joining("\n"));
}
public void writeComment(Writer output, int offset, CommentStyle defaultStyle) throws IOException {
CommentStyle style = commentStyle != null ? commentStyle : defaultStyle;
int minSpacing = 0, borderSpacing = 0;

View File

@ -177,6 +177,15 @@ public class ConfigSection extends MemoryConfiguration {
return result;
}
@Nullable
public String getCommentString(@NotNull String path) {
Comment result = root.configComments.get(fullPath + path);
if (result == null) {
result = root.defaultComments.get(fullPath + path);
}
return result != null ? result.toString() : null;
}
@Override
public void addDefault(@NotNull String path, @Nullable Object value) {
root.defaults.put(fullPath + path, value);

View File

@ -1,33 +1,180 @@
package com.songoda.core.configuration.editor;
import com.songoda.core.compatibility.LegacyMaterials;
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 java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemoryConfiguration;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
public class ConfigEditorGui extends SimplePagedGui {
final JavaPlugin plugin;
final String file;
final MemoryConfiguration config;
List<String> keys = new ArrayList();
final ConfigurationSection node;
Method configSection_getCommentString = null;
List<String> sections = new ArrayList();
List<String> settings = new ArrayList();
public ConfigEditorGui(String file, MemoryConfiguration config) {
this(file, config, config);
public ConfigEditorGui(JavaPlugin plugin, Gui parent, String file, MemoryConfiguration config) {
this(plugin, parent, file, config, config);
setOnClose((gui) -> save());
}
public ConfigEditorGui(String file, MemoryConfiguration config, MemoryConfiguration node) {
public ConfigEditorGui(JavaPlugin plugin, Gui parent, String file, MemoryConfiguration config, ConfigurationSection node) {
super(parent);
this.plugin = plugin;
this.file = file;
this.config = config;
this.node = node;
this.blankItem = GuiUtils.getBorderItem(LegacyMaterials.LIGHT_GRAY_STAINED_GLASS_PANE);
// if we have a ConfigSection, we can also grab comments
try {
configSection_getCommentString = node.getClass().getDeclaredMethod("getCommentString", String.class);
} catch (Exception ex) {
}
// decorate header
this.setTitle(ChatColor.DARK_BLUE + file);
this.setUseHeader(true);
headerBackItem = footerBackItem = GuiUtils.getBorderItem(LegacyMaterials.GRAY_STAINED_GLASS_PANE.getItem());
final String path = node.getCurrentPath();
this.setItem(4, configItem(LegacyMaterials.FILLED_MAP, path, config, path, null));
this.setButton(8, GuiUtils.createButtonItem(LegacyMaterials.OAK_DOOR, "Exit"), (event) -> event.player.closeInventory());
// compile list of settings
for (String key : node.getKeys(false)) {
if (node.isConfigurationSection(key)) {
sections.add(key);
keys.add(key); // sections listed first
} else {
settings.add(key);
}
}
keys.addAll(settings); // normal settings next
// next we need to display the config settings, with the ability to browse more pages
// next we need to display the config settings
int index = 9;
for (final String sectionKey : sections) {
this.setButton(index++, configItem(LegacyMaterials.WRITABLE_BOOK, ChatColor.YELLOW + sectionKey, node, sectionKey, "Click to open this section"),
(event) -> event.manager.showGUI(event.player, new ConfigEditorGui(plugin, this, file, config, node.getConfigurationSection(sectionKey))));
}
// todo: display values of settings in gui, too
// now display individual settings
for (final String settingKey : settings) {
final Object val = node.get(settingKey);
if(val == null) continue;
else if(val instanceof Boolean) {
// toggle switch
this.setButton(index, configItem(LegacyMaterials.LEVER, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf((Boolean) val), "Click to toggle this setting"),
(event) -> this.toggle(event.slot, settingKey));
if((Boolean) val) {
this.highlightItem(index);
}
} else if (isNumber(val)) {
// number dial
this.setButton(index, configItem(LegacyMaterials.CLOCK, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf((Number) val), "Click to edit this setting"),
(event) -> {
event.gui.exit();
ChatPrompt prompt = ChatPrompt.showPrompt(plugin, event.player, "Enter your new value.", response -> {
if (!setNumber(event.slot, settingKey, response.getMessage().trim())) {
event.player.sendMessage(ChatColor.RED + "Error: \"" + response.getMessage().trim() + "\" is not a number!");
}
});
prompt.setOnClose(() -> event.manager.showGUI(event.player, this));
});
}
++index;
}
}
void toggle(int clickCell, String path) {
boolean val = !node.getBoolean(path);
node.set(path, val);
if(val) {
inventory.setItem(clickCell, ItemUtils.addGlow(inventory.getItem(clickCell)));
} else {
removeHighlight(clickCell);
}
}
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));
}
} catch (NumberFormatException e) {
return false;
}
return true;
}
void save() {
// 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;
}
}
plugin.reloadConfig();
}
private boolean isNumber(Object value) {
return value != null && (
value instanceof Long
|| value instanceof Integer
|| value instanceof Float
|| value instanceof Double);
}
ItemStack configItem(LegacyMaterials type, String name, ConfigurationSection node, String path, String def) {
String[] info = null;
if (configSection_getCommentString != null) {
try {
Object comment = configSection_getCommentString.invoke(config, path);
if (comment != null) {
info = comment.toString().split("\n");
}
} catch (Exception ex) {
}
}
return GuiUtils.createButtonItem(LegacyMaterials.FILLED_MAP, path, info != null ? info : (def != null ? def.split("\n") : null));
}
ItemStack configItem(LegacyMaterials 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(config, path);
if (comment != null) {
info = (value + "\n" + comment.toString()).split("\n");
}
} catch (Exception ex) {
}
}
return GuiUtils.createButtonItem(LegacyMaterials.FILLED_MAP, path, info != null ? info : (def != null ? (value + "\n" + def).split("\n") : null));
}
}

View File

@ -14,8 +14,7 @@ import java.util.List;
import java.util.Map;
import org.bukkit.ChatColor;
import org.bukkit.configuration.MemoryConfiguration;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
/**
* Edit all configuration files for a specific plugin
@ -25,7 +24,7 @@ import org.bukkit.plugin.Plugin;
*/
public class PluginConfigGui extends SimplePagedGui {
final Plugin plugin;
final JavaPlugin plugin;
LinkedHashMap<String, MemoryConfiguration> configs = new LinkedHashMap();
public PluginConfigGui(SongodaPlugin plugin) {
@ -47,11 +46,11 @@ public class PluginConfigGui extends SimplePagedGui {
init();
}
public PluginConfigGui(Plugin plugin) {
public PluginConfigGui(JavaPlugin plugin) {
this(plugin, null);
}
public PluginConfigGui(Plugin plugin, Gui parent) {
public PluginConfigGui(JavaPlugin plugin, Gui parent) {
super(parent);
this.plugin = plugin;
@ -68,7 +67,7 @@ public class PluginConfigGui extends SimplePagedGui {
for (Object cfg : ((List) more)) {
configs.put(((File) method_Config_getFile.invoke(cfg)).getName(), (MemoryConfiguration) cfg);
}
} catch (Exception ex) {
} catch (Exception ex) {
// include a failsafe, I guess
((List) more).forEach(cfg -> configs.put("(File " + configs.size() + ")", (MemoryConfiguration) cfg));
}
@ -80,6 +79,7 @@ public class PluginConfigGui extends SimplePagedGui {
}
private void init() {
this.blankItem = GuiUtils.getBorderItem(LegacyMaterials.LIGHT_GRAY_STAINED_GLASS_PANE);
// decorate header
this.setTitle(ChatColor.DARK_BLUE + plugin.getName() + " Plugin Config");
@ -91,7 +91,7 @@ public class PluginConfigGui extends SimplePagedGui {
int i = 9;
for (Map.Entry<String, MemoryConfiguration> config : configs.entrySet()) {
this.setButton(i++, GuiUtils.createButtonItem(LegacyMaterials.BOOK, ChatColor.YELLOW + config.getKey(), "Click to edit this config"),
(event) -> event.manager.showGUI(event.player, new ConfigEditorGui(config.getKey(), config.getValue())));
(event) -> event.manager.showGUI(event.player, new ConfigEditorGui(plugin, this, config.getKey(), config.getValue())));
}
}

View File

@ -32,7 +32,7 @@ public class GuiManager {
final Plugin plugin;
final UUID uuid = UUID.randomUUID(); // manager tracking to fix weird bugs from lazy programming
final GuiListener listener = new GuiListener(this);
final Map<Player, Inventory> openInventories = new HashMap();
final Map<Player, Gui> openInventories = new HashMap();
private boolean initialized = false;
private boolean shutdown = false;
@ -70,10 +70,14 @@ public class GuiManager {
} else if (!initialized) {
init();
}
Gui openInv = openInventories.get(player);
if(openInv != null) {
openInv.open = false;
}
Inventory inv = gui.generateInventory(this);
player.openInventory(inv);
gui.onOpen(this, player);
openInventories.put(player, inv);
openInventories.put(player, gui);
}
public void showPopup(Player player, String message) {
@ -160,6 +164,9 @@ public class GuiManager {
if (openInv.getHolder() != null && openInv.getHolder() instanceof GuiHolder
&& ((GuiHolder) openInv.getHolder()).manager.uuid.equals(manager.uuid)) {
Gui gui = ((GuiHolder) openInv.getHolder()).getGUI();
if(!gui.open) {
return;
}
final Player player = (Player) event.getPlayer();
if (!gui.allowDropItems) {
player.setItemOnCursor(null);

View File

@ -53,6 +53,23 @@ public class SimplePagedGui extends Gui {
return this;
}
@Override
public SimplePagedGui setItem(int row, int col, ItemStack item) {
return setItem(col + row * 9, item);
}
@Override
public SimplePagedGui setItem(int cell, ItemStack item) {
// set the cell relative to the current page
int cellIndex = page == 1 || (useHeader && cell < 9) ? cell : (cell + (page - 1) * (rowsPerPage * 9));
cellItems.put(cellIndex, item);
if (open && cell >= 0 && cell < inventory.getSize()) {
inventory.setItem(cell, item);
}
return this;
}
@Override
public void nextPage() {
if (page < pages) {
@ -109,7 +126,7 @@ public class SimplePagedGui extends Gui {
int maxRows = (int) Math.ceil(maxCellSlot / 9.);
pages = (int) Math.ceil(maxRows / rowsPerPage);
page = 1;
this.setRows(maxRows + 1);
this.setRows(maxRows + (useHeader ? 2 : 1));
// create inventory view
final int cells = rows * 9;
@ -148,8 +165,7 @@ public class SimplePagedGui extends Gui {
// footer row
conditionals = conditionalButtons.get(cell - (rows * 9));
} else {
int startCell = useHeader ? 9 : 0;
int cellIndex = startCell + (page - 1) * rowsPerPage;
int cellIndex = page == 1 || (useHeader && cell < 9) ? cell : (cell + (page - 1) * (rowsPerPage * 9));
conditionals = conditionalButtons.get(cellIndex);
}