From c687d18385bba1ccb2c3a821652203121887181a Mon Sep 17 00:00:00 2001 From: Florian CUNY Date: Wed, 10 Apr 2019 14:37:14 +0200 Subject: [PATCH] Introducing the BentoBox Management Panel (/bbox manage) As it mostly relies on other panels yet-to-be-implemented, it doesn't do much. But it was fun to do! --- .../bentobox/commands/BentoBoxCommand.java | 5 +- .../commands/BentoBoxManageCommand.java | 31 +++ .../bentobox/panels/ManagementPanel.java | 205 ++++++++++++++++++ src/main/resources/locales/en-US.yml | 33 +++ 4 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 src/main/java/world/bentobox/bentobox/commands/BentoBoxManageCommand.java create mode 100644 src/main/java/world/bentobox/bentobox/panels/ManagementPanel.java diff --git a/src/main/java/world/bentobox/bentobox/commands/BentoBoxCommand.java b/src/main/java/world/bentobox/bentobox/commands/BentoBoxCommand.java index 1cc87a4e0..8acf7c579 100644 --- a/src/main/java/world/bentobox/bentobox/commands/BentoBoxCommand.java +++ b/src/main/java/world/bentobox/bentobox/commands/BentoBoxCommand.java @@ -1,10 +1,10 @@ package world.bentobox.bentobox.commands; -import java.util.List; - import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.user.User; +import java.util.List; + public class BentoBoxCommand extends CompositeCommand { /** @@ -19,6 +19,7 @@ public class BentoBoxCommand extends CompositeCommand { setPermission("bentobox.admin"); new BentoBoxVersionCommand(this); new BentoBoxAboutCommand(this); + new BentoBoxManageCommand(this); new BentoBoxReloadCommand(this); } diff --git a/src/main/java/world/bentobox/bentobox/commands/BentoBoxManageCommand.java b/src/main/java/world/bentobox/bentobox/commands/BentoBoxManageCommand.java new file mode 100644 index 000000000..9fd7c07a7 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/commands/BentoBoxManageCommand.java @@ -0,0 +1,31 @@ +package world.bentobox.bentobox.commands; + +import world.bentobox.bentobox.api.commands.CompositeCommand; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.panels.ManagementPanel; + +import java.util.List; + +/** + * Displays the Management panel. + * + * @author Poslovitch + * @since 1.5.0 + */ +public class BentoBoxManageCommand extends CompositeCommand { + + public BentoBoxManageCommand(CompositeCommand parent) { + super(parent, "manage", "overview"); + } + + @Override + public void setup() { + setOnlyPlayer(true); + } + + @Override + public boolean execute(User user, String label, List args) { + ManagementPanel.openPanel(user, ManagementPanel.View.GAMEMODES); + return true; + } +} diff --git a/src/main/java/world/bentobox/bentobox/panels/ManagementPanel.java b/src/main/java/world/bentobox/bentobox/panels/ManagementPanel.java new file mode 100644 index 000000000..6bb11a7d8 --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/panels/ManagementPanel.java @@ -0,0 +1,205 @@ +package world.bentobox.bentobox.panels; + +import org.bukkit.Material; +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.api.addons.Addon; +import world.bentobox.bentobox.api.addons.GameModeAddon; +import world.bentobox.bentobox.api.panels.PanelItem; +import world.bentobox.bentobox.api.panels.builders.PanelBuilder; +import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder; +import world.bentobox.bentobox.api.user.User; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Poslovitch + * @since 1.5.0 + */ +public class ManagementPanel { + + private static final String LOCALE_REF = "management.panel."; + private static final int[] PANES = {0, 4, 7, 8, 9, 18, 26, 27, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44}; + + private ManagementPanel() {} + + /** + * Dynamically creates the panel. + * @param user the User to show the panel to + */ + public static void openPanel(User user, View view) { + BentoBox plugin = BentoBox.getInstance(); + + PanelBuilder builder = new PanelBuilder() + .name(user.getTranslation(LOCALE_REF + "title")) + .size(45); + + // Setup header and corner + setupHeader(builder, user, view); + for (int i : PANES) { + builder.item(i, new PanelItemBuilder().icon(Material.LIGHT_BLUE_STAINED_GLASS_PANE).name(" ").build()); + } + + // Setup the views + int startSlot = 10; + int i = 0; + List addons; + switch (view) { + case GAMEMODES: + addons = plugin.getAddonsManager().getGameModeAddons(); + if (addons.isEmpty()) { + looksEmpty(builder, user); + break; + } + for (Addon addon : addons) { + PanelItem addonItem = new PanelItemBuilder() + .icon(addon.getDescription().getIcon()) + .name(addon.getDescription().getName()) + .build(); + + builder.item(startSlot + i, addonItem); + + PanelItem schems = new PanelItemBuilder() + .icon(Material.STRUCTURE_BLOCK) + .name(user.getTranslation(LOCALE_REF + "views.gamemodes.schems.name")) + .description(user.getTranslation(LOCALE_REF + "views.gamemodes.schems.description")) + .clickHandler((panel, user1, clickType, slot) -> { + user1.sendRawMessage("opening the admin schems menu (not implemented yet)"); + return true; + }) + .build(); + + builder.item(startSlot + i + 9, schems); + i++; + } + break; + case ADDONS: + addons = plugin.getAddonsManager().getEnabledAddons().stream().filter(addon -> !(addon instanceof GameModeAddon)).collect(Collectors.toList()); + if (addons.isEmpty()) { + looksEmpty(builder, user); + break; + } + for (Addon addon : addons) { + PanelItem addonItem = new PanelItemBuilder() + .icon(addon.getDescription().getIcon()) + .name(addon.getDescription().getName()) + .build(); + + builder.item(startSlot + i, addonItem); + i++; + } + break; + case HOOKS: + looksEmpty(builder, user); + + break; + } + + // Setup a few more buttons + // Catalog + PanelItem catalog = new PanelItemBuilder() + .icon(Material.ENCHANTED_BOOK) + .name(user.getTranslation(LOCALE_REF + "buttons.catalog.name")) + .description(user.getTranslation(LOCALE_REF + "buttons.catalog.description")) + .clickHandler((panel, user1, clickType, slot) -> { + user1.sendRawMessage("opening the catalog... (not implemented yet)"); + return true; + }) + .build(); + + builder.item(17, catalog); + + // Show it to the user + builder.build().open(user); + } + + private static void setupHeader(PanelBuilder builder, User user, View view) { + // Navigation buttons + PanelItemBuilder gamemodesIconBuilder = new PanelItemBuilder() + .icon(Material.COMMAND_BLOCK) + .name(user.getTranslation(LOCALE_REF + "views.gamemodes.name")) + .description(user.getTranslation(LOCALE_REF + "views.gamemodes.description")) + .clickHandler((panel, user1, clickType, slot) -> { + openPanel(user, View.GAMEMODES); + return true; + }); + + PanelItemBuilder addonsIconBuilder = new PanelItemBuilder() + .icon(Material.BOOK) + .name(user.getTranslation(LOCALE_REF + "views.addons.name")) + .description(user.getTranslation(LOCALE_REF + "views.addons.description")) + .clickHandler((panel, user1, clickType, slot) -> { + openPanel(user, View.ADDONS); + return true; + }); + + PanelItemBuilder hooksIconBuilder = new PanelItemBuilder() + .icon(Material.TRIPWIRE_HOOK) + .name(user.getTranslation(LOCALE_REF + "views.hooks.name")) + .description(user.getTranslation(LOCALE_REF + "views.hooks.description")) + .clickHandler((panel, user1, clickType, slot) -> { + openPanel(user, View.HOOKS); + return true; + }); + + switch (view) { + case GAMEMODES: + gamemodesIconBuilder.glow(true); + break; + case ADDONS: + addonsIconBuilder.glow(true); + break; + case HOOKS: + hooksIconBuilder.glow(true); + break; + } + + builder.item(1, gamemodesIconBuilder.build()); + builder.item(2, addonsIconBuilder.build()); + builder.item(3, hooksIconBuilder.build()); + + // Global action buttons + PanelItem checkUpdatesItem = new PanelItemBuilder() + .icon(Material.OBSERVER) + .name(user.getTranslation(LOCALE_REF + "actions.check-updates.name")) + .description(user.getTranslation(LOCALE_REF + "actions.check-updates.description")) + .clickHandler((panel, user1, clickType, slot) -> { + user1.sendRawMessage("checking for updates (not implemented yet)"); + return true; + }) + .build(); + + PanelItem reloadItem = new PanelItemBuilder() + .icon(Material.REDSTONE_TORCH) + .name(user.getTranslation(LOCALE_REF + "actions.reload.name")) + .description(user.getTranslation(LOCALE_REF + "actions.reload.description")) + .clickHandler((panel, user1, clickType, slot) -> { + user1.performCommand("bentobox reload"); + return true; + }) + .build(); + + builder.item(5, checkUpdatesItem); + builder.item(6, reloadItem); + } + + private static void looksEmpty(PanelBuilder builder, User user) { + PanelItem emptyHere = new PanelItemBuilder() + .icon(Material.STRUCTURE_VOID) + .name(user.getTranslation(LOCALE_REF + "buttons.empty-here.name")) + .description(user.getTranslation(LOCALE_REF + "buttons.empty-here.description")) + .clickHandler((panel, user1, clickType, slot) -> { + user1.sendRawMessage("opening the catalog... (not implemented yet)"); + return true; + }) + .build(); + + builder.item(22, emptyHere); + } + + public enum View { + GAMEMODES, + ADDONS, + HOOKS + } +} diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index fc3a1f3ab..000fdf659 100644 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -262,6 +262,8 @@ commands: addon-syntax: "&2[name] &3[version]" game-worlds: "&2[name] &3([addon])" server: "&2Running &3[name] [version]&2." + manage: + description: "display the management panel" confirmation: confirm: "&cType command again within &b[seconds]s&c to confirm." previous-request-cancelled: "&6Previous confirmation request cancelled." @@ -940,6 +942,37 @@ language: selected: "&aCurrently selected." edited: "&aChanged your language to &e[lang]&a." +management: + panel: + title: "BentoBox Management" + views: + gamemodes: + name: "&6Gamemodes" + description: "&eClick &ato display currently loaded Gamemodes" + schems: + name: "&6Schems" + description: "&aOpens the Admin Schem menu." + addons: + name: "&6Addons" + description: "&eClick &ato display currently loaded Addons" + hooks: + name: "&6Hooks" + description: "&eClick &ato display currently loaded Hooks" + actions: + check-updates: + name: "&6Check for updates" + description: "&eClick &ato check for updates" + reload: + name: "&cReload" + description: "&eClick &c<wice &r&ato reload BentoBox" + buttons: + catalog: + name: "&6Addons Catalog" + description: "&aOpens the Addons Catalog" + empty-here: + name: "&bThis looks empty here..." + description: "&aWhat if you take a look at our catalog?" + successfully-loaded: | &6 ____ _ ____