add newest core preference, fix paged gui + list editor

This commit is contained in:
jascotty2 2019-09-01 13:14:57 -05:00
parent 927aee51bf
commit fcdb9d2d50
11 changed files with 160 additions and 69 deletions

View File

@ -12,6 +12,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
@ -23,6 +24,7 @@ import java.util.UUID;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
@ -31,6 +33,7 @@ import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.ServicePriority; import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
@ -39,13 +42,18 @@ public class SongodaCore {
private final static String prefix = "[SongodaCore]"; private final static String prefix = "[SongodaCore]";
/**
* Whenever we make a major change to the core GUI, updater,
* or other function used by the core, increment this number
*/
private final static int coreRevision = 2;
private final static int updaterVersion = 1; private final static int updaterVersion = 1;
private final static Set<PluginInfo> registeredPlugins = new HashSet<>(); private final static Set<PluginInfo> registeredPlugins = new HashSet<>();
private static SongodaCore INSTANCE = null; private static SongodaCore INSTANCE = null;
private JavaPlugin piggybackedPlugin; private JavaPlugin piggybackedPlugin;
private final CommandManager commandManager; private CommandManager commandManager;
private EventListener loginListener; private EventListener loginListener;
private ShadedEventListener shadingListener; private ShadedEventListener shadingListener;
@ -64,13 +72,45 @@ public class SongodaCore {
for (Class<?> clazz : Bukkit.getServicesManager().getKnownServices()) { for (Class<?> clazz : Bukkit.getServicesManager().getKnownServices()) {
if(clazz.getSimpleName().equals("SongodaCore")) { if(clazz.getSimpleName().equals("SongodaCore")) {
try { try {
// use the active service // test to see if we're up to date
clazz.getMethod("registerPlugin", JavaPlugin.class, int.class, String.class).invoke(null, plugin, pluginID, icon); int otherVersion = (int) clazz.getMethod("getCoreVersion").invoke(null);
if(otherVersion >= getCoreVersion()) {
// use the active service
clazz.getMethod("registerPlugin", JavaPlugin.class, int.class, String.class).invoke(null, plugin, pluginID, icon);
if(hasShading()) { if(hasShading()) {
(INSTANCE = new SongodaCore()).piggybackedPlugin = plugin; (INSTANCE = new SongodaCore()).piggybackedPlugin = plugin;
INSTANCE.shadingListener = new ShadedEventListener(); INSTANCE.shadingListener = new ShadedEventListener();
Bukkit.getPluginManager().registerEvents(INSTANCE.shadingListener, plugin); Bukkit.getPluginManager().registerEvents(INSTANCE.shadingListener, plugin);
}
} else {
// we are newer than the registered service: steal all of its registrations
// grab the old core's registrations
List otherPlugins = (List) clazz.getMethod("getPlugins").invoke(null);
// destroy the old core
Object oldCore = clazz.getMethod("getInstance").invoke(null);
Method destruct = clazz.getDeclaredMethod("destroy");
destruct.setAccessible(true);
destruct.invoke(oldCore);
// register ourselves as the SongodaCore service!
INSTANCE = new SongodaCore(plugin);
INSTANCE.init();
INSTANCE.register(plugin, pluginID, icon);
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, plugin, ServicePriority.Normal);
// we need (JavaPlugin plugin, int pluginID, String icon) for our object
if(!otherPlugins.isEmpty()) {
Object testSubject = otherPlugins.get(0);
Class otherPluginInfo = testSubject.getClass();
Method otherPluginInfo_getJavaPlugin = otherPluginInfo.getMethod("getJavaPlugin");
Method otherPluginInfo_getSongodaId = otherPluginInfo.getMethod("getSongodaId");
Method otherPluginInfo_getCoreIcon = otherPluginInfo.getMethod("getCoreIcon");
for(Object other : otherPlugins) {
INSTANCE.register(
(JavaPlugin) otherPluginInfo_getJavaPlugin.invoke(other),
(int) otherPluginInfo_getSongodaId.invoke(other),
(String) otherPluginInfo_getCoreIcon.invoke(other));
}
}
} }
return; return;
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) { } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) {
@ -80,9 +120,9 @@ public class SongodaCore {
// register ourselves as the SongodaCore service! // register ourselves as the SongodaCore service!
INSTANCE = new SongodaCore(plugin); INSTANCE = new SongodaCore(plugin);
INSTANCE.init(); INSTANCE.init();
INSTANCE.register(plugin, pluginID, icon);
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, plugin, ServicePriority.Normal); Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, plugin, ServicePriority.Normal);
} }
INSTANCE.register(plugin, pluginID, icon);
} }
SongodaCore() { SongodaCore() {
@ -97,17 +137,35 @@ public class SongodaCore {
private void init() { private void init() {
shadingListener = new ShadedEventListener(); shadingListener = new ShadedEventListener();
commandManager.registerCommandDynamically(new SongodaCoreCommand(this)) commandManager.registerCommandDynamically(new SongodaCoreCommand())
.addSubCommand(new SongodaCoreDiagCommand(this)); .addSubCommand(new SongodaCoreDiagCommand());
Bukkit.getPluginManager().registerEvents(loginListener, piggybackedPlugin); Bukkit.getPluginManager().registerEvents(loginListener, piggybackedPlugin);
Bukkit.getPluginManager().registerEvents(shadingListener, piggybackedPlugin); Bukkit.getPluginManager().registerEvents(shadingListener, piggybackedPlugin);
// we aggressevely want to own this command // we aggressevely want to own this command
Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, ()->{CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);}, 10 * 60 * 1); tasks.add(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); tasks.add(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); tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, ()->{CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);}, 20 * 60 * 2));
Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, ()->registerAllPlugins(), 20 * 60 * 2); tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, ()->registerAllPlugins(), 20 * 60 * 2));
} }
/**
* Used to yield this core to a newer core
*/
private void destroy() {
Bukkit.getServicesManager().unregister(SongodaCore.class, INSTANCE);
tasks.stream().filter(task -> task != null && !task.isCancelled())
.forEach(task -> Bukkit.getScheduler().cancelTask(task.getTaskId()));
HandlerList.unregisterAll(loginListener);
if(!hasShading()) {
HandlerList.unregisterAll(shadingListener);
}
registeredPlugins.clear();
piggybackedPlugin = null;
commandManager = null;
loginListener = null;
}
private ArrayList<BukkitTask> tasks = new ArrayList();
/** /**
* Register plugins that may not have been updated yet * Register plugins that may not have been updated yet
*/ */
@ -179,7 +237,7 @@ public class SongodaCore {
// don't forget to check for language pack updates ;) // don't forget to check for language pack updates ;)
info.addModule(new LocaleModule()); info.addModule(new LocaleModule());
registeredPlugins.add(info); registeredPlugins.add(info);
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, () -> update(info), 20L); tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, () -> update(info), 60L));
} }
private void update(PluginInfo plugin) { private void update(PluginInfo plugin) {
@ -223,11 +281,15 @@ public class SongodaCore {
} }
} }
public List<PluginInfo> getPlugins() { public static List<PluginInfo> getPlugins() {
return new ArrayList<>(registeredPlugins); return new ArrayList<>(registeredPlugins);
} }
public static int getVersion() { public static int getCoreVersion() {
return coreRevision;
}
public static int getUpdaterVersion() {
return updaterVersion; return updaterVersion;
} }

View File

@ -45,7 +45,6 @@ public abstract class SongodaPlugin extends JavaPlugin {
@Override @Override
public ConfigFileConfigurationAdapter getConfig() { public ConfigFileConfigurationAdapter getConfig() {
System.out.println("Plugin config adapter!");
return config.getFileConfig(); return config.getFileConfig();
} }

View File

@ -7,7 +7,6 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;

View File

@ -62,7 +62,7 @@ public class ConfigEditorGui extends SimplePagedGui {
this.setUseHeader(true); this.setUseHeader(true);
headerBackItem = footerBackItem = GuiUtils.getBorderItem(LegacyMaterials.GRAY_STAINED_GLASS_PANE.getItem()); headerBackItem = footerBackItem = GuiUtils.getBorderItem(LegacyMaterials.GRAY_STAINED_GLASS_PANE.getItem());
final String path = node.getCurrentPath(); final String path = node.getCurrentPath();
this.setItem(4, configItem(LegacyMaterials.FILLED_MAP, !path.isEmpty() ? path : file , config, !path.isEmpty() ? path : null, null)); this.setItem(4, configItem(LegacyMaterials.FILLED_MAP, !path.isEmpty() ? path : file , config, !path.isEmpty() ? path : null, ChatColor.BLACK.toString()));
this.setButton(8, GuiUtils.createButtonItem(LegacyMaterials.OAK_DOOR, "Exit"), (event) -> event.player.closeInventory()); this.setButton(8, GuiUtils.createButtonItem(LegacyMaterials.OAK_DOOR, "Exit"), (event) -> event.player.closeInventory());
// compile list of settings // compile list of settings
@ -77,21 +77,20 @@ public class ConfigEditorGui extends SimplePagedGui {
// next we need to display the config settings // next we need to display the config settings
int index = 9; int index = 9;
for (final String sectionKey : sections) { for (final String sectionKey : sections) {
this.setButton(index++, configItem(LegacyMaterials.WRITABLE_BOOK, ChatColor.YELLOW + sectionKey, node, sectionKey, "Click to open this section"), 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)))); (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 // now display individual settings
for (final String settingKey : settings) { for (final String settingKey : settings) {
final Object val = node.get(settingKey); final Object val = node.get(settingKey);
if(val == null) continue; if(val == null) continue;
else if(val instanceof Boolean) { else if (val instanceof Boolean) {
// toggle switch // toggle switch
this.setButton(index, configItem(LegacyMaterials.LEVER, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf((Boolean) val), "Click to toggle this setting"), 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)); (event) -> this.toggle(event.slot, settingKey));
if((Boolean) val) { if ((Boolean) val) {
this.highlightItem(index); highlightItem(index);
} }
} else if (isNumber(val)) { } else if (isNumber(val)) {
// number dial // number dial
@ -108,7 +107,7 @@ public class ConfigEditorGui extends SimplePagedGui {
} else if (isMaterial(val)) { } else if (isMaterial(val)) {
// changing a block // changing a block
// isMaterial is more of a guess, to be honest. // isMaterial is more of a guess, to be honest.
this.setButton(index, configItem(LegacyMaterials.STONE, ChatColor.YELLOW + settingKey, node, settingKey, val.toString(), "Click to edit this setting"), setButton(index, configItem(LegacyMaterials.STONE, ChatColor.YELLOW + settingKey, node, settingKey, val.toString(), "Click to edit this setting"),
(event) -> { (event) -> {
SimplePagedGui paged = new SimplePagedGui(this); SimplePagedGui paged = new SimplePagedGui(this);
paged.setTitle(ChatColor.BLUE + settingKey); paged.setTitle(ChatColor.BLUE + settingKey);
@ -126,7 +125,7 @@ public class ConfigEditorGui extends SimplePagedGui {
} else if (val instanceof String) { } else if (val instanceof String) {
// changing a "string" value (or change to a feather for writing quill) // changing a "string" value (or change to a feather for writing quill)
this.setButton(index, configItem(LegacyMaterials.STRING, ChatColor.YELLOW + settingKey, node, settingKey, val.toString(), "Click to edit this setting"), setButton(index, configItem(LegacyMaterials.STRING, ChatColor.YELLOW + settingKey, node, settingKey, val.toString(), "Click to edit this setting"),
(event) -> { (event) -> {
event.gui.exit(); event.gui.exit();
ChatPrompt.showPrompt(plugin, event.player, "Enter a new value for " + settingKey + ":", response -> { ChatPrompt.showPrompt(plugin, event.player, "Enter a new value for " + settingKey + ":", response -> {
@ -136,11 +135,11 @@ public class ConfigEditorGui extends SimplePagedGui {
.setOnCancel(() -> {event.player.sendMessage(ChatColor.RED + "Edit canceled"); 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) { } else if (val instanceof List) {
this.setButton(index, configItem(LegacyMaterials.WRITABLE_BOOK, ChatColor.YELLOW + settingKey, node, settingKey, String.format("(%d values)", ((List) val).size()), "Click to edit this setting"), setButton(index, configItem(LegacyMaterials.WRITABLE_BOOK, ChatColor.YELLOW + settingKey, node, settingKey, String.format("(%d values)", ((List) val).size()), "Click to edit this setting"),
(event) -> { (event) -> {
event.manager.showGUI(event.player, (new ConfigEditorListEditorGui(this, settingKey, (List) val)).setOnClose((gui) -> { event.manager.showGUI(event.player, (new ConfigEditorListEditorGui(this, settingKey, (List) val)).setOnClose((gui) -> {
if(((ConfigEditorListEditorGui) gui.gui).saveChanges) { if(((ConfigEditorListEditorGui) gui.gui).saveChanges) {
setList(event.slot, settingKey, ((ConfigEditorListEditorGui) gui.gui).value); setList(event.slot, settingKey, ((ConfigEditorListEditorGui) gui.gui).values);
} }
})); }));
}); });

View File

@ -6,6 +6,7 @@ import com.songoda.core.gui.SimplePagedGui;
import com.songoda.core.input.ChatPrompt; import com.songoda.core.input.ChatPrompt;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
@ -20,9 +21,10 @@ public class ConfigEditorListEditorGui extends SimplePagedGui {
final ConfigEditorGui current; final ConfigEditorGui current;
public boolean saveChanges = false; public boolean saveChanges = false;
public List<String> value; public List<String> values;
public ConfigEditorListEditorGui(ConfigEditorGui current, String key, List<String> value) { public ConfigEditorListEditorGui(ConfigEditorGui current, String key, List<String> val) {
super(current);
this.current = current; this.current = current;
this.blankItem = current.getDefaultItem(); this.blankItem = current.getDefaultItem();
headerBackItem = footerBackItem = current.getHeaderBackItem(); headerBackItem = footerBackItem = current.getHeaderBackItem();
@ -30,7 +32,7 @@ public class ConfigEditorListEditorGui extends SimplePagedGui {
this.setUseHeader(true); this.setUseHeader(true);
this.setItem(4, current.configItem(LegacyMaterials.FILLED_MAP, key, current.getCurrentNode(), key, null)); this.setItem(4, current.configItem(LegacyMaterials.FILLED_MAP, key, current.getCurrentNode(), key, null));
this.setButton(8, GuiUtils.createButtonItem(LegacyMaterials.OAK_DOOR, "Exit"), (event) -> event.player.closeInventory()); this.setButton(8, GuiUtils.createButtonItem(LegacyMaterials.OAK_DOOR, "Exit"), (event) -> event.player.closeInventory());
this.value = new ArrayList(value); this.values = new ArrayList(val);
this.setButton(8, GuiUtils.createButtonItem(LegacyMaterials.LAVA_BUCKET, ChatColor.RED + "Discard Changes"), (event) -> event.player.closeInventory()); this.setButton(8, GuiUtils.createButtonItem(LegacyMaterials.LAVA_BUCKET, ChatColor.RED + "Discard Changes"), (event) -> event.player.closeInventory());
this.setButton(0, GuiUtils.createButtonItem(LegacyMaterials.REDSTONE, ChatColor.GREEN + "Save"), (event) -> { this.setButton(0, GuiUtils.createButtonItem(LegacyMaterials.REDSTONE, ChatColor.GREEN + "Save"), (event) -> {
@ -39,34 +41,40 @@ public class ConfigEditorListEditorGui extends SimplePagedGui {
}); });
this.setButton(1, GuiUtils.createButtonItem(LegacyMaterials.CHEST, ChatColor.BLUE + "Add Item"), this.setButton(1, GuiUtils.createButtonItem(LegacyMaterials.CHEST, ChatColor.BLUE + "Add Item"),
(event) -> { (event) -> {
event.gui.exit();
ChatPrompt.showPrompt(event.manager.getPlugin(), event.player, "Enter a new value to add:", response -> { ChatPrompt.showPrompt(event.manager.getPlugin(), event.player, "Enter a new value to add:", response -> {
value.add(response.getMessage().trim()); values.add(response.getMessage().trim());
redraw(); redraw();
}).setOnClose(() -> event.manager.showGUI(event.player, this)) }).setOnClose(() -> {event.manager.showGUI(event.player, this); })
.setOnCancel(() -> {event.player.sendMessage(ChatColor.RED + "Edit canceled"); event.manager.showGUI(event.player, this);}); .setOnCancel(() -> {event.player.sendMessage(ChatColor.RED + "Edit canceled"); event.manager.showGUI(event.player, this);});
}); });
redraw();
} }
void redraw() { void redraw() {
page = 1; page = 1;
// clear old display // clear old display
for (Integer oldI : (Integer[]) cellItems.keySet().toArray()) { if(inventory != null) {
if (oldI > 8) { for(Integer i : cellItems.keySet().toArray(new Integer[0])) {
cellItems.remove(oldI); if(i > 8) {
cellItems.remove(i);
conditionalButtons.remove(i);
}
} }
} }
// update items // update items
int i = 9; int i = 9;
for (String item : value) { for (String item : values) {
final int index = i - 9; final int index = i - 9;
setButton(i++, GuiUtils.createButtonItem(LegacyMaterials.PAPER, item, "Right-click to remove"), ClickType.RIGHT, (event) -> { setButton(i++, GuiUtils.createButtonItem(LegacyMaterials.PAPER, item, "Right-click to remove"), ClickType.RIGHT, (event) -> {
value.remove(index); values.remove(index);
redraw(); redraw();
}); });
} }
// update display // update display
showPage(); update();
} }
} }

View File

@ -94,4 +94,8 @@ public final class PluginInfo {
public int getSongodaId() { public int getSongodaId() {
return songodaId; return songodaId;
} }
public String getCoreIcon() {
return coreIcon;
}
} }

View File

@ -9,12 +9,10 @@ import org.bukkit.entity.Player;
public class SongodaCoreCommand extends AbstractCommand { public class SongodaCoreCommand extends AbstractCommand {
final SongodaCore instance;
protected GuiManager guiManager; protected GuiManager guiManager;
public SongodaCoreCommand(SongodaCore instance) { public SongodaCoreCommand() {
super(false, "songoda"); super(false, "songoda");
this.instance = instance;
} }
@Override @Override
@ -23,7 +21,7 @@ public class SongodaCoreCommand extends AbstractCommand {
if(guiManager == null || guiManager.isClosed()) { if(guiManager == null || guiManager.isClosed()) {
guiManager = new GuiManager(SongodaCore.getHijackedPlugin()); guiManager = new GuiManager(SongodaCore.getHijackedPlugin());
} }
guiManager.showGUI((Player) sender, new SongodaCoreOverviewGUI(instance)); guiManager.showGUI((Player) sender, new SongodaCoreOverviewGUI());
} else { } else {
sender.sendMessage("/songoda diag"); sender.sendMessage("/songoda diag");
} }

View File

@ -15,16 +15,13 @@ import java.util.List;
public class SongodaCoreDiagCommand extends AbstractCommand { public class SongodaCoreDiagCommand extends AbstractCommand {
final SongodaCore instance;
private final DecimalFormat format = new DecimalFormat("##.##"); private final DecimalFormat format = new DecimalFormat("##.##");
private Object serverInstance; private Object serverInstance;
private Field tpsField; private Field tpsField;
public SongodaCoreDiagCommand(SongodaCore instance) { public SongodaCoreDiagCommand() {
super(false, "diag"); super(false, "diag");
this.instance = instance;
try { try {
serverInstance = NMSUtils.getNMSClass("MinecraftServer").getMethod("getServer").invoke(null); serverInstance = NMSUtils.getNMSClass("MinecraftServer").getMethod("getServer").invoke(null);
@ -42,7 +39,7 @@ public class SongodaCoreDiagCommand extends AbstractCommand {
sender.sendMessage("Songoda Diagnostics Information"); sender.sendMessage("Songoda Diagnostics Information");
sender.sendMessage(""); sender.sendMessage("");
sender.sendMessage("Plugins:"); sender.sendMessage("Plugins:");
for (PluginInfo plugin : instance.getPlugins()) { for (PluginInfo plugin : SongodaCore.getPlugins()) {
sender.sendMessage(plugin.getJavaPlugin().getName() sender.sendMessage(plugin.getJavaPlugin().getName()
+ " (" + plugin.getJavaPlugin().getDescription().getVersion() + ")"); + " (" + plugin.getJavaPlugin().getDescription().getVersion() + ")");
} }

View File

@ -11,11 +11,8 @@ import org.bukkit.event.inventory.ClickType;
final class SongodaCoreOverviewGUI extends Gui { final class SongodaCoreOverviewGUI extends Gui {
private final SongodaCore update; protected SongodaCoreOverviewGUI() {
List<PluginInfo> plugins = SongodaCore.getPlugins();
protected SongodaCoreOverviewGUI(SongodaCore update) {
this.update = update;
List<PluginInfo> plugins = update.getPlugins();
// could do pages, too, but don't think we'll have that many at a time for a while // could do pages, too, but don't think we'll have that many at a time for a while
int max = (int) Math.ceil(plugins.size() / 9.); int max = (int) Math.ceil(plugins.size() / 9.);
setRows(max); setRows(max);

View File

@ -140,36 +140,63 @@ public class SimplePagedGui extends Gui {
protected Inventory generateInventory(GuiManager manager) { protected Inventory generateInventory(GuiManager manager) {
// calculate pages here // calculate pages here
rowsPerPage = useHeader ? 4 : 5; rowsPerPage = useHeader ? 4 : 5;
maxCellSlot = this.cellItems.isEmpty() ? 0 : this.cellItems.keySet().stream().max(Integer::compare).get(); maxCellSlot = (this.cellItems.isEmpty() ? 0 : this.cellItems.keySet().stream().max(Integer::compare).get()) + 1;
int maxRows = (int) Math.ceil(maxCellSlot / 9.); int maxRows = (int) Math.ceil(maxCellSlot / 9.);
pages = (int) Math.ceil(maxRows / rowsPerPage); pages = (int) Math.ceil(maxRows / rowsPerPage);
page = 1; this.setRows(maxRows + (useHeader ? 1 : 0));
this.setRows(maxRows + (useHeader ? 2 : 1));
// create inventory view // create inventory view
final int cells = rows * 9; final int cells = rows * 9;
inventory = Bukkit.getServer().createInventory(new GuiHolder(manager, this), cells, inventory = Bukkit.getServer().createInventory(new GuiHolder(manager, this), cells,
title == null ? "" : trimTitle(ChatColor.translateAlternateColorCodes('&', title))); title == null ? "" : trimTitle(ChatColor.translateAlternateColorCodes('&', title)));
// populate initial inventory // populate and return the display inventory
page = 1;
update();
return inventory;
}
@Override
public void update() {
if (inventory == null) {
return;
}
// calculate pages here
rowsPerPage = useHeader ? 4 : 5;
maxCellSlot = (this.cellItems.isEmpty() ? 0 : this.cellItems.keySet().stream().max(Integer::compare).get()) + 1;
int maxRows = Math.max((useHeader ? 1 : 0), (int) Math.ceil(maxCellSlot / 9.));
pages = (int) Math.ceil(maxRows / rowsPerPage);
// create a new inventory if needed
final int cells = rows * 9;
boolean isNew = false;
if (cells != inventory.getSize()) {
this.setRows(maxRows + (useHeader ? 2 : 1));
inventory = Bukkit.getServer().createInventory(inventory.getHolder(), cells,
title == null ? "" : trimTitle(ChatColor.translateAlternateColorCodes('&', title)));
isNew = true;
}
// populate header
if (useHeader) { if (useHeader) {
for (int i = 0; i < 9; ++i) { for (int i = 0; i < 9; ++i) {
final ItemStack item = cellItems.get(i); final ItemStack item = cellItems.get(i);
inventory.setItem(i, item != null ? item : (headerBackItem != null ? headerBackItem : blankItem)); inventory.setItem(i, item != null ? item : (headerBackItem != null ? headerBackItem : blankItem));
} }
} }
for (int i = useHeader ? 9 : 0; i < cells - 9; ++i) {
final ItemStack item = cellItems.get(i);
inventory.setItem(i, item != null ? item : blankItem);
}
// last row is dedicated to pagation // last row is dedicated to pagation
for (int i = cells - 9; i < cells; ++i) { for (int i = cells - 9; i < cells; ++i) {
inventory.setItem(i, footerBackItem != null ? footerBackItem : blankItem); inventory.setItem(i, footerBackItem != null ? footerBackItem : blankItem);
} }
updatePageNavigation(); // fill out the rest of the page
showPage();
return inventory; if(isNew) {
// whoopsie!
exit();
getPlayers().forEach(player -> ((GuiHolder) inventory.getHolder()).manager.showGUI(player, this));
}
} }
@Override @Override

View File

@ -74,6 +74,7 @@ public class ChatPrompt implements Listener {
ChatConfirmEvent chatConfirmEvent = new ChatConfirmEvent(player, event.getMessage()); ChatConfirmEvent chatConfirmEvent = new ChatConfirmEvent(player, event.getMessage());
player.sendMessage("\u00BB " + event.getMessage());
try { try {
handler.onChat(chatConfirmEvent); handler.onChat(chatConfirmEvent);
} catch (Throwable t) { } catch (Throwable t) {