diff --git a/pom.xml b/pom.xml index 04bb273..44659be 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ com.rsscripting RS-Warehouse RS-Warehouse - 1.4.0 + 1.5.0 21 diff --git a/src/main/java/com/rsscripting/rswarehouse/adminmenu/AdminMenu.java b/src/main/java/com/rsscripting/rswarehouse/adminmenu/AdminMenu.java index c3da23d..7a8f560 100644 --- a/src/main/java/com/rsscripting/rswarehouse/adminmenu/AdminMenu.java +++ b/src/main/java/com/rsscripting/rswarehouse/adminmenu/AdminMenu.java @@ -195,6 +195,16 @@ public class AdminMenu { ) ); + menu.setItem( + 14, + RSMenuUtils.createMenuItemWithLore( + Material.COMMAND_BLOCK, + "§aCreate Server Rule", + List.of( + "§7Create a server rule entry." + ) + ) + ); player.openInventory(menu); diff --git a/src/main/java/com/rsscripting/rswarehouse/adminmenu/AdminMenuListener.java b/src/main/java/com/rsscripting/rswarehouse/adminmenu/AdminMenuListener.java index 9f87888..a866ceb 100644 --- a/src/main/java/com/rsscripting/rswarehouse/adminmenu/AdminMenuListener.java +++ b/src/main/java/com/rsscripting/rswarehouse/adminmenu/AdminMenuListener.java @@ -1,5 +1,6 @@ package com.rsscripting.rswarehouse.adminmenu; +import com.rsscripting.rswarehouse.serverrule.ServerRuleInternalNameMenu; import com.rsscripting.rswarehouse.session.admin.ServerCommandCreationSessionManager; import com.rsscripting.rswarehouse.config.ConfigManager; import com.rsscripting.rswarehouse.chestconvert.ConvertMenuListener; @@ -9,6 +10,7 @@ import com.rsscripting.rswarehouse.constants.RSConstants; import com.rsscripting.rswarehouse.navigation.NavigationManager; import com.rsscripting.rswarehouse.servercommands.ServerCommandInternalNameMenu; import com.rsscripting.rswarehouse.session.GuiSessionManager; +import com.rsscripting.rswarehouse.session.admin.ServerRuleCreationSessionManager; import org.bukkit.block.Block; import com.rsscripting.rswarehouse.utils.RSMessageUtils; import org.bukkit.entity.Player; @@ -147,6 +149,19 @@ public class AdminMenuListener return; } + if (event.getRawSlot() == 14) { + + ServerRuleCreationSessionManager.createSession( + player.getUniqueId() + ); + + ServerRuleInternalNameMenu.open( + player + ); + + return; + } + } } \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/category/categorymenu/CategoryMenu.java b/src/main/java/com/rsscripting/rswarehouse/category/categorymenu/CategoryMenu.java index 009070f..557e0a3 100644 --- a/src/main/java/com/rsscripting/rswarehouse/category/categorymenu/CategoryMenu.java +++ b/src/main/java/com/rsscripting/rswarehouse/category/categorymenu/CategoryMenu.java @@ -102,6 +102,9 @@ public class CategoryMenu { WarehouseCategory serverCommands = null; + WarehouseCategory serverRules = + null; + List displayCategories = new ArrayList<>(); @@ -122,13 +125,21 @@ public class CategoryMenu { } else if (category.id() == 1001) { - if (ConfigManager.isServerCommandsEnabled()) { serverCommands = category; } + } + else if (category.id() == 1000) { + + if (ConfigManager.isServerRulesEnabled()) { + + serverRules = category; + + } + } else { @@ -482,6 +493,54 @@ public class CategoryMenu { } + if (serverRules != null) { + + ItemStack icon = + RSMenuUtils.createMenuItemWithLore( + Material.valueOf( + serverRules.material() + ), + "§a" + + serverRules.displayName(), + serverRules.lore() == null + || serverRules.lore().isBlank() + ? List.of() + : Arrays.asList( + serverRules.lore() + .split("\n") + ) + ); + + ItemMeta meta = + icon.getItemMeta(); + + if (meta != null) { + + meta.addItemFlags( + ItemFlag.HIDE_ATTRIBUTES, + ItemFlag.HIDE_ADDITIONAL_TOOLTIP + ); + + meta.getPersistentDataContainer() + .set( + RSKeys.CATEGORY_ID, + PersistentDataType.INTEGER, + serverRules.id() + ); + + icon.setItemMeta( + meta + ); + + } + + menu.setItem( + 7, + icon + ); + + } + player.openInventory( menu ); diff --git a/src/main/java/com/rsscripting/rswarehouse/config/ConfigManager.java b/src/main/java/com/rsscripting/rswarehouse/config/ConfigManager.java index 254d1f5..4b15abf 100644 --- a/src/main/java/com/rsscripting/rswarehouse/config/ConfigManager.java +++ b/src/main/java/com/rsscripting/rswarehouse/config/ConfigManager.java @@ -81,5 +81,13 @@ public class ConfigManager { } + public static boolean isServerRulesEnabled() { + + return config.getBoolean( + "display.show-server-rules", + true + ); + + } } \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/dao/admin/CreateServerRuleDAO.java b/src/main/java/com/rsscripting/rswarehouse/dao/admin/CreateServerRuleDAO.java new file mode 100644 index 0000000..5835e7a --- /dev/null +++ b/src/main/java/com/rsscripting/rswarehouse/dao/admin/CreateServerRuleDAO.java @@ -0,0 +1,257 @@ +package com.rsscripting.rswarehouse.dao.admin; + +import com.rsscripting.rswarehouse.database.DatabaseManager; +import com.rsscripting.rswarehouse.utils.ItemStackUtils; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.Statement; +import java.sql.SQLException; + +public class CreateServerRuleDAO { + + public static int createServerRule( + String internalName, + String displayName, + String material, + String lore + ) { + + try ( + Connection connection = + DatabaseManager.getConnection() + ) { + + connection.setAutoCommit(false); + + try { + + /* + * Create the Server Rule category. + */ + + int nextDisplayOrder = 1; + + try ( + PreparedStatement maxStatement = + connection.prepareStatement( + """ + SELECT COALESCE( + MAX(display_order), + 0 + ) + FROM warehouse_categories + """ + ) + ) { + + ResultSet resultSet = + maxStatement.executeQuery(); + + if (resultSet.next()) { + + nextDisplayOrder = + resultSet.getInt(1) + 1; + + } + + } + + int ruleCategoryId; + + try ( + PreparedStatement statement = + connection.prepareStatement( + """ + INSERT INTO warehouse_categories ( + parent_category_id, + internal_name, + display_name, + material, + lore, + display_order, + page, + slot + ) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + """, + Statement.RETURN_GENERATED_KEYS + ) + ) { + + statement.setInt( + 1, + 1000 + ); + + statement.setString( + 2, + internalName + ); + + statement.setString( + 3, + displayName + ); + + statement.setString( + 4, + material + ); + + statement.setString( + 5, + lore + ); + + statement.setInt( + 6, + nextDisplayOrder + ); + + statement.setInt( + 7, + 0 + ); + + statement.setInt( + 8, + 0 + ); + + statement.executeUpdate(); + + ResultSet keys = + statement.getGeneratedKeys(); + + if (!keys.next()) { + + connection.rollback(); + + return -1; + + } + + ruleCategoryId = + keys.getInt(1); + + } + + + /* + * Create the display-only navigation item. + */ + + ItemStack item = + new ItemStack( + Material.valueOf( + material + ) + ); + + String serializedItem = + ItemStackUtils.serialize( + item + ); + + try ( + PreparedStatement statement = + connection.prepareStatement( + """ + INSERT INTO warehouse_items ( + category_id, + serialized_item, + default_lore, + inventory_id, + subcategory_id, + created_at, + page, + slot + ) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + """ + ) + ) { + + statement.setInt( + 1, + 1000 + ); + + statement.setString( + 2, + serializedItem + ); + + statement.setString( + 3, + null + ); + + statement.setObject( + 4, + null + ); + + statement.setInt( + 5, + ruleCategoryId + ); + + statement.setString( + 6, + String.valueOf( + System.currentTimeMillis() + ) + ); + + statement.setObject( + 7, + null + ); + + statement.setObject( + 8, + null + ); + + statement.executeUpdate(); + + } + + connection.commit(); + + return ruleCategoryId; + + } + + catch (SQLException exception) { + + connection.rollback(); + + exception.printStackTrace(); + + } + + finally { + + connection.setAutoCommit(true); + + } + + } + + catch (SQLException exception) { + + exception.printStackTrace(); + + } + + return -1; + + } + +} \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/database/DatabaseTableCreator.java b/src/main/java/com/rsscripting/rswarehouse/database/DatabaseTableCreator.java index b4d4011..4a5efa9 100644 --- a/src/main/java/com/rsscripting/rswarehouse/database/DatabaseTableCreator.java +++ b/src/main/java/com/rsscripting/rswarehouse/database/DatabaseTableCreator.java @@ -92,6 +92,31 @@ public class DatabaseTableCreator { """ ); + connection.createStatement().execute( + """ + INSERT OR IGNORE INTO warehouse_categories ( + id, + internal_name, + display_name, + material, + lore, + display_order, + page, + slot + ) + VALUES ( + 1000, + 'server_rules', + 'Server Rules', + 'BOOK', + '\nRules and guidelines for this server.', + 0, + 0, + 7 + ) + """ + ); + connection.createStatement().execute( """ INSERT OR IGNORE INTO warehouse_categories ( diff --git a/src/main/java/com/rsscripting/rswarehouse/registration/ListenerRegistration.java b/src/main/java/com/rsscripting/rswarehouse/registration/ListenerRegistration.java index c2d7f46..0970156 100644 --- a/src/main/java/com/rsscripting/rswarehouse/registration/ListenerRegistration.java +++ b/src/main/java/com/rsscripting/rswarehouse/registration/ListenerRegistration.java @@ -7,6 +7,7 @@ import com.rsscripting.rswarehouse.category.categoryedit.CategoryEditLoreMenuCha import com.rsscripting.rswarehouse.category.categoryedit.CategoryEditLoreMenuListener; import com.rsscripting.rswarehouse.category.categoryedit.CategoryEditMaterialMenuListener; import com.rsscripting.rswarehouse.servercommands.*; +import com.rsscripting.rswarehouse.serverrule.*; import com.rsscripting.rswarehouse.subcategory.items.*; import com.rsscripting.rswarehouse.adminmenu.AdminMenuListener; import com.rsscripting.rswarehouse.assignpageslot.CategoryPageNumberMenuListener; @@ -343,6 +344,33 @@ public final class ListenerRegistration { new PartiallyFilledVariantsMenuListener() ); + /* Server Rules */ + + ListenerRegistrar.register( + plugin, + new ServerRuleDisplayNameMenuListener() + ); + + ListenerRegistrar.register( + plugin, + new ServerRuleInternalNameMenuListener() + ); + + ListenerRegistrar.register( + plugin, + new ServerRuleLoreChatListener() + ); + + ListenerRegistrar.register( + plugin, + new ServerRuleLoreMenuListener() + ); + + ListenerRegistrar.register( + plugin, + new ServerRuleMaterialPickerMenuListener() + ); + } } \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/servercommands/ServerCommandLoreMenu.java b/src/main/java/com/rsscripting/rswarehouse/servercommands/ServerCommandLoreMenu.java index 18156be..b280846 100644 --- a/src/main/java/com/rsscripting/rswarehouse/servercommands/ServerCommandLoreMenu.java +++ b/src/main/java/com/rsscripting/rswarehouse/servercommands/ServerCommandLoreMenu.java @@ -121,7 +121,7 @@ public class ServerCommandLoreMenu { 22, RSMenuUtils.createMenuItem( Material.LIME_WOOL, - "§aCreate Server Command" + "§aSave Lore and Proceed to Material Picker" ) ); diff --git a/src/main/java/com/rsscripting/rswarehouse/servercommands/ServerCommandLoreMenuListener.java b/src/main/java/com/rsscripting/rswarehouse/servercommands/ServerCommandLoreMenuListener.java index 9aeb5e2..793837d 100644 --- a/src/main/java/com/rsscripting/rswarehouse/servercommands/ServerCommandLoreMenuListener.java +++ b/src/main/java/com/rsscripting/rswarehouse/servercommands/ServerCommandLoreMenuListener.java @@ -122,7 +122,7 @@ public class ServerCommandLoreMenuListener () -> { if ( - session.getPendingServerCommandLoreExpiration() + session.getPendingServerCommandLoreExpiration() != expiration ) { diff --git a/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleDisplayNameMenu.java b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleDisplayNameMenu.java new file mode 100644 index 0000000..36429a8 --- /dev/null +++ b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleDisplayNameMenu.java @@ -0,0 +1,95 @@ +package com.rsscripting.rswarehouse.serverrule; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.MenuType; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.view.AnvilView; + +import java.util.List; + + +public class ServerRuleDisplayNameMenu { + + public static final String TITLE = + "Rule Display Title"; + + public static void open(Player player) { + + AnvilView view = MenuType.ANVIL + .builder() + .title( + Component.text( + TITLE + ) + ) + .build(player); + + + ItemStack confirm = + new ItemStack( + Material.LIME_WOOL + ); + + ItemMeta meta = + confirm.getItemMeta(); + + meta.displayName( + Component.text("") + ); + + meta.lore( + List.of( + Component.text( + "Save and proceed to description." + ).color( + NamedTextColor.WHITE + ) + ) + ); + + confirm.setItemMeta(meta); + + view.setItem( + 0, + confirm + ); + + + ItemStack cancel = + new ItemStack( + Material.RED_WOOL + ); + + ItemMeta metacancel = + cancel.getItemMeta(); + + metacancel.displayName( + Component.text("") + ); + + metacancel.lore( + List.of( + Component.text( + "Cancel" + ).color( + NamedTextColor.WHITE + ) + ) + ); + + cancel.setItemMeta(metacancel); + + view.setItem( + 1, + cancel + ); + + view.open(); + + } + +} \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleDisplayNameMenuListener.java b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleDisplayNameMenuListener.java new file mode 100644 index 0000000..d181500 --- /dev/null +++ b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleDisplayNameMenuListener.java @@ -0,0 +1,155 @@ +package com.rsscripting.rswarehouse.serverrule; + +import com.rsscripting.rswarehouse.adminmenu.AdminMenu; +import com.rsscripting.rswarehouse.utils.RSMessageUtils; +import com.rsscripting.rswarehouse.session.admin.ServerRuleCreationSession; +import com.rsscripting.rswarehouse.session.admin.ServerRuleCreationSessionManager; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.view.AnvilView; + + +public class ServerRuleDisplayNameMenuListener + implements Listener { + + + @EventHandler + public void onInventoryClick( + InventoryClickEvent event + ) { + + if (!(event.getView() + instanceof AnvilView anvilView)) { + + return; + + } + + if (!event.getView() + .title() + .toString() + .contains( + ServerRuleDisplayNameMenu.TITLE + )) { + + return; + + } + + Player player = + (Player) event.getWhoClicked(); + + + ServerRuleCreationSession session = + ServerRuleCreationSessionManager.getSession( + player.getUniqueId() + ); + + if (session == null) { + + return; + + } + + event.setCancelled(true); + + + if (event.getCurrentItem() == null) { + + return; + + } + + + if (event.getRawSlot() == 0) { + + String categoryName = + anvilView.getRenameText(); + + if (categoryName.length() > 25) { + + RSMessageUtils.error( + player, + "Rule titles may not exceed 25 characters." + ); + + return; + + } + + if (categoryName.isBlank()) { + + RSMessageUtils.error( + player, + "Rule title cannot be empty." + ); + + return; + + } + + session.setPendingServerRuleDisplayName( + categoryName + ); + + event.getView() + .getTopInventory() + .clear(); + + ServerRuleLoreMenu.open( + player + ); + + return; + + } + + + if (event.getRawSlot() == 1) { + + event.getView() + .getTopInventory() + .clear(); + + AdminMenu.open( + player + ); + + } + + } + + + @EventHandler + public void onInventoryClose( + InventoryCloseEvent event + ) { + + if (!(event.getView() + instanceof AnvilView)) { + + return; + + } + + if (!event.getView() + .title() + .toString() + .contains( + ServerRuleDisplayNameMenu.TITLE + )) { + + return; + + } + + event.getView() + .getTopInventory() + .clear(); + + } + +} \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleInternalNameMenu.java b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleInternalNameMenu.java new file mode 100644 index 0000000..64e6eef --- /dev/null +++ b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleInternalNameMenu.java @@ -0,0 +1,95 @@ +package com.rsscripting.rswarehouse.serverrule; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.MenuType; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.view.AnvilView; + +import java.util.List; + + +public class ServerRuleInternalNameMenu { + + public static final String TITLE = + "Rule Internal Name"; + + public static void open(Player player) { + + AnvilView view = MenuType.ANVIL + .builder() + .title( + Component.text( + TITLE + ) + ) + .build(player); + + + ItemStack confirm = + new ItemStack( + Material.LIME_WOOL + ); + + ItemMeta meta = + confirm.getItemMeta(); + + meta.displayName( + Component.text("") + ); + + meta.lore( + List.of( + Component.text( + "Save and proceed to title." + ).color( + NamedTextColor.WHITE + ) + ) + ); + + confirm.setItemMeta(meta); + + view.setItem( + 0, + confirm + ); + + + ItemStack cancel = + new ItemStack( + Material.RED_WOOL + ); + + ItemMeta metacancel = + cancel.getItemMeta(); + + metacancel.displayName( + Component.text("") + ); + + metacancel.lore( + List.of( + Component.text( + "Cancel" + ).color( + NamedTextColor.WHITE + ) + ) + ); + + cancel.setItemMeta(metacancel); + + view.setItem( + 1, + cancel + ); + + view.open(); + + } + +} \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleInternalNameMenuListener.java b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleInternalNameMenuListener.java new file mode 100644 index 0000000..19b643c --- /dev/null +++ b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleInternalNameMenuListener.java @@ -0,0 +1,156 @@ +package com.rsscripting.rswarehouse.serverrule; + +import com.rsscripting.rswarehouse.adminmenu.AdminMenu; +import com.rsscripting.rswarehouse.session.admin.ServerRuleCreationSession; +import com.rsscripting.rswarehouse.session.admin.ServerRuleCreationSessionManager; +import com.rsscripting.rswarehouse.utils.RSMessageUtils; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.view.AnvilView; + + +public class ServerRuleInternalNameMenuListener + implements Listener { + + + @EventHandler + public void onInventoryClick( + InventoryClickEvent event + ) { + + if (!(event.getView() + instanceof AnvilView anvilView)) { + + return; + + } + + if (!event.getView() + .title() + .toString() + .contains( + ServerRuleInternalNameMenu.TITLE + )) { + + return; + + } + + Player player = + (Player) event.getWhoClicked(); + + event.setCancelled(true); + + + ServerRuleCreationSession session = + ServerRuleCreationSessionManager.getSession( + player.getUniqueId() + ); + + if (session == null) { + + return; + + } + + if (event.getCurrentItem() == null) { + + return; + + } + + + if (event.getRawSlot() == 0) { + + String categoryName = + anvilView.getRenameText(); + + if (categoryName.length() > 25) { + + RSMessageUtils.error( + player, + "Rule names may not exceed 25 characters." + ); + + return; + + } + + if (categoryName.isBlank()) { + + RSMessageUtils.error( + player, + "Rule name cannot be empty." + ); + + return; + + } + + session.setPendingServerRuleName( + categoryName + ); + + event.getView() + .getTopInventory() + .clear(); + + + ServerRuleDisplayNameMenu.open( + player + ); + + + return; + + } + + + if (event.getRawSlot() == 1) { + + event.getView() + .getTopInventory() + .clear(); + + AdminMenu.open( + player + ); + + } + + } + + + @EventHandler + public void onInventoryClose( + InventoryCloseEvent event + ) { + + if (!(event.getView() + instanceof AnvilView)) { + + return; + + } + + if (!event.getView() + .title() + .toString() + .contains( + ServerRuleInternalNameMenu.TITLE + )) { + + return; + + } + + event.getView() + .getTopInventory() + .clear(); + + } + +} \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleLoreChatListener.java b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleLoreChatListener.java new file mode 100644 index 0000000..81eb0cc --- /dev/null +++ b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleLoreChatListener.java @@ -0,0 +1,100 @@ +package com.rsscripting.rswarehouse.serverrule; + +import com.rsscripting.rswarehouse.session.admin.ServerRuleCreationSession; +import com.rsscripting.rswarehouse.session.admin.ServerRuleCreationSessionManager; +import com.rsscripting.rswarehouse.utils.RSMessageUtils; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +public class ServerRuleLoreChatListener + implements Listener { + + @EventHandler + public void onChat( + AsyncPlayerChatEvent event + ) { + + Player player = + event.getPlayer(); + + ServerRuleCreationSession session = + ServerRuleCreationSessionManager.getSession( + player.getUniqueId() + ); + + if (session == null) { + + return; + + } + + int loreSlot = + session.getPendingServerRuleLoreSlot(); + + if (loreSlot < 0) { + + return; + + } + + event.setCancelled(true); + + String message = + event.getMessage(); + + if ( + message.equalsIgnoreCase( + "cancel" + ) + ) { + + session.setPendingServerRuleLoreSlot( + -1 + ); + + session.setPendingServerRuleLoreExpiration( + 0 + ); + + ServerRuleLoreMenu.open( + player + ); + + return; + + } + + session.setPendingServerRuleLore( + loreSlot, + message + ); + + session.setPendingServerRuleLoreSlot( + -1 + ); + + session.setPendingServerRuleLoreExpiration( + 0 + ); + + RSMessageUtils.info( + player, + "Lore saved." + ); + + Bukkit.getScheduler().runTask( + Bukkit.getPluginManager() + .getPlugin( + "RS-Warehouse" + ), + () -> ServerRuleLoreMenu.open( + player + ) + ); + + } + +} \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleLoreMenu.java b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleLoreMenu.java new file mode 100644 index 0000000..2506a29 --- /dev/null +++ b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleLoreMenu.java @@ -0,0 +1,156 @@ +package com.rsscripting.rswarehouse.serverrule; + +import com.rsscripting.rswarehouse.menuholder.RSMenuHolder; +import com.rsscripting.rswarehouse.session.admin.ServerRuleCreationSession; +import com.rsscripting.rswarehouse.session.admin.ServerRuleCreationSessionManager; +import com.rsscripting.rswarehouse.utils.RSMenuUtils; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.List; + + +public class ServerRuleLoreMenu { + + public static void open( + Player player + ) { + + Inventory menu = + Bukkit.createInventory( + new RSMenuHolder( + "SERVER_RULE_LORE" + ), + 27, + Component.text( + "Server Rule Lore" + ) + ); + + + for (int i = 0; i < menu.getSize(); i++) { + + menu.setItem( + i, + RSMenuUtils.createFillerPane() + ); + + } + + + ServerRuleCreationSession session = + ServerRuleCreationSessionManager.getSession( + player.getUniqueId() + ); + + + for (int i = 0; i < 5; i++) { + + ItemStack book = + new ItemStack( + Material.WRITABLE_BOOK + ); + + ItemMeta meta = + book.getItemMeta(); + + meta.displayName( + Component.text( + "Lore Line " + + (i + 1) + ) + ); + + + List lore = + new ArrayList<>(); + + String value = + session.getPendingServerRuleLore( + i + ); + + + if ( + value == null + || value.isBlank() + ) { + + lore.add( + Component.text( + "(Empty)" + ) + ); + + } + + else { + + lore.add( + Component.text( + value + ) + ); + + } + + + lore.add( + Component.empty() + ); + + lore.add( + Component.text( + "Click to edit." + ) + ); + + + meta.lore( + lore + ); + + book.setItemMeta( + meta + ); + + + menu.setItem( + 11 + i, + book + ); + + } + + + menu.setItem( + 22, + RSMenuUtils.createMenuItem( + Material.LIME_WOOL, + "§aSave Lore and Proceed to Material Picker" + ) + ); + + + menu.setItem( + 4, + RSMenuUtils.createMenuItem( + Material.OAK_DOOR, + "§eBack" + ) + ); + + + player.openInventory( + menu + ); + + } + +} \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleLoreMenuListener.java b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleLoreMenuListener.java new file mode 100644 index 0000000..94ba0fb --- /dev/null +++ b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleLoreMenuListener.java @@ -0,0 +1,182 @@ +package com.rsscripting.rswarehouse.serverrule; + +import com.rsscripting.rswarehouse.menuholder.RSMenuHolder; +import com.rsscripting.rswarehouse.session.admin.ServerRuleCreationSession; +import com.rsscripting.rswarehouse.session.admin.ServerRuleCreationSessionManager; +import com.rsscripting.rswarehouse.utils.RSMessageUtils; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; + + +public class ServerRuleLoreMenuListener + implements Listener { + + + @EventHandler + public void onInventoryClick( + InventoryClickEvent event + ) { + + if (!(event.getInventory() + .getHolder() + instanceof RSMenuHolder holder)) { + + return; + + } + + if (!holder.getMenuId().equals( + "SERVER_RULE_LORE" + )) { + + return; + + } + + event.setCancelled( + true + ); + + Player player = + (Player) event.getWhoClicked(); + + ServerRuleCreationSession session = + ServerRuleCreationSessionManager.getSession( + player.getUniqueId() + ); + + if (session == null) { + + return; + + } + + switch (event.getSlot()) { + + case 4 -> ServerRuleDisplayNameMenu.open( + player + ); + + case 11 -> editLore( + player, + session, + 0 + ); + + case 12 -> editLore( + player, + session, + 1 + ); + + case 13 -> editLore( + player, + session, + 2 + ); + + case 14 -> editLore( + player, + session, + 3 + ); + + case 15 -> editLore( + player, + session, + 4 + ); + + case 22 -> { + + ServerRuleMaterialPickerMenu.open( + player, + 0 + ); + + } + + } + + } + + + private void editLore( + Player player, + ServerRuleCreationSession session, + int loreSlot + ) { + + session.setPendingServerRuleLoreSlot( + loreSlot + ); + + session.setPendingServerRuleLoreExpiration( + System.currentTimeMillis() + + 30000 + ); + + final long expiration = + session.getPendingServerRuleLoreExpiration(); + + Bukkit.getScheduler() + .runTaskLater( + Bukkit.getPluginManager() + .getPlugin( + "RS-Warehouse" + ), + () -> { + + if ( + session.getPendingServerRuleLoreExpiration() + != expiration + ) { + + return; + + } + + session.setPendingServerRuleLoreSlot( + -1 + ); + + session.setPendingServerRuleLoreExpiration( + 0 + ); + + RSMessageUtils.error( + player, + "Lore input timed out." + ); + + }, + 20L * 30 + ); + + + player.closeInventory(); + + + RSMessageUtils.info( + player, + "Enter lore for line " + + (loreSlot + 1) + + " in chat." + ); + + RSMessageUtils.info( + player, + "Type 'cancel' to abort." + ); + + RSMessageUtils.info( + player, + "Auto-Cancels after 30 seconds." + ); + + } + +} \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleMaterialPickerMenu.java b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleMaterialPickerMenu.java new file mode 100644 index 0000000..1c5bbb5 --- /dev/null +++ b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleMaterialPickerMenu.java @@ -0,0 +1,125 @@ +package com.rsscripting.rswarehouse.serverrule; + +import com.rsscripting.rswarehouse.menuholder.RSMenuHolder; +import com.rsscripting.rswarehouse.utils.RSMenuUtils; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; +import java.util.List; + + +public class ServerRuleMaterialPickerMenu { + + public static void open( + Player player, + int page + ) { + + Inventory menu = + Bukkit.createInventory( + new RSMenuHolder( + "SERVER_RULE_MATERIAL_PICKER" + ), + 54, + "Select Rule Material" + ); + + + int slot = 0; + + + List materials = + Arrays.stream( + Material.values() + ) + .filter( + Material::isItem + ) + .filter( + material -> + !material.name().endsWith( + "_SMITHING_TEMPLATE" + ) + ) + .toList(); + + + int startIndex = + page * 45; + + + int maxPages = + (int) Math.ceil( + (double) materials.size() + / 45 + ); + + + for ( + int inventorySlot = 0; + inventorySlot < 45; + inventorySlot++ + ) { + + int materialIndex = + startIndex + inventorySlot; + + + if ( + materialIndex >= materials.size() + ) { + + break; + + } + + + menu.setItem( + inventorySlot, + new ItemStack( + materials.get( + materialIndex + ) + ) + ); + + } + + + if (page > 0) { + + menu.setItem( + 45, + RSMenuUtils.createMenuItem( + Material.ARROW, + "§cPrevious Page" + ) + ); + + } + + + if (page < maxPages - 1) { + + menu.setItem( + 53, + RSMenuUtils.createMenuItem( + Material.ARROW, + "§aNext Page" + ) + ); + + } + + + player.openInventory( + menu + ); + + } + +} \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleMaterialPickerMenuListener.java b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleMaterialPickerMenuListener.java new file mode 100644 index 0000000..12c8857 --- /dev/null +++ b/src/main/java/com/rsscripting/rswarehouse/serverrule/ServerRuleMaterialPickerMenuListener.java @@ -0,0 +1,193 @@ +package com.rsscripting.rswarehouse.serverrule; + +import com.rsscripting.rswarehouse.dao.admin.CreateServerRuleDAO; +import com.rsscripting.rswarehouse.item.ItemsMenu; +import com.rsscripting.rswarehouse.menuholder.RSMenuHolder; +import com.rsscripting.rswarehouse.session.admin.ServerRuleCreationSession; +import com.rsscripting.rswarehouse.session.admin.ServerRuleCreationSessionManager; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; + + +public class ServerRuleMaterialPickerMenuListener + implements Listener { + + + @EventHandler + public void onInventoryClick( + InventoryClickEvent event + ) { + + if (!(event.getInventory() + .getHolder() + instanceof RSMenuHolder holder)) { + + return; + + } + + + if (!holder.getMenuId().equals( + "SERVER_RULE_MATERIAL_PICKER" + )) { + + return; + + } + + + event.setCancelled( + true + ); + + + if (event.getCurrentItem() == null) { + + return; + + } + + + Player player = + (Player) event.getWhoClicked(); + + + ServerRuleCreationSession session = + ServerRuleCreationSessionManager.getSession( + player.getUniqueId() + ); + + + if (session == null) { + + player.closeInventory(); + + return; + + } + + + /* + * Previous page + */ + + if (event.getSlot() == 45) { + + ServerRuleMaterialPickerMenu.open( + player, + 0 + ); + + return; + + } + + + /* + * Next page + */ + + if (event.getSlot() == 53) { + + ServerRuleMaterialPickerMenu.open( + player, + 1 + ); + + return; + + } + + + /* + * Save selected material. + */ + + session.setPendingServerRuleMaterial( + event.getCurrentItem() + .getType() + .name() + ); + + + int ruleCategoryId = + CreateServerRuleDAO.createServerRule( + session.getPendingServerRuleName(), + session.getPendingServerRuleDisplayName(), + session.getPendingServerRuleMaterial(), + buildLore(session) + ); + + + if (ruleCategoryId == -1) { + + player.sendMessage( + "§cFailed to create Server Rule." + ); + + return; + + } + + + player.sendMessage( + "§aServer Rule created successfully." + ); + + + ItemsMenu.open( + player, + 1000, + "Server Rules", + 0 + ); + + } + + + private String buildLore( + ServerRuleCreationSession session + ) { + + StringBuilder loreBuilder = + new StringBuilder(); + + + for (int i = 0; i < 5; i++) { + + String line = + session.getPendingServerRuleLore( + i + ); + + + if (line == null) { + + line = ""; + + } + + + loreBuilder.append( + line + ); + + + if (i < 4) { + + loreBuilder.append( + "\n" + ); + + } + + } + + + return loreBuilder.toString(); + + } + +} \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/session/admin/ServerRuleCreationSession.java b/src/main/java/com/rsscripting/rswarehouse/session/admin/ServerRuleCreationSession.java new file mode 100644 index 0000000..f35e2d5 --- /dev/null +++ b/src/main/java/com/rsscripting/rswarehouse/session/admin/ServerRuleCreationSession.java @@ -0,0 +1,132 @@ +package com.rsscripting.rswarehouse.session.admin; + +public class ServerRuleCreationSession { + + private String pendingServerRuleName; + + private String pendingServerRuleDisplayName; + + private final String[] pendingServerRuleLore = + new String[5]; + + private int pendingServerRuleLoreSlot = -1; + + private long pendingServerRuleLoreExpiration; + + private String pendingServerRuleMaterial; + + + public String getPendingServerRuleName() { + + return pendingServerRuleName; + + } + + public void setPendingServerRuleName( + String pendingServerRuleName + ) { + + this.pendingServerRuleName = + pendingServerRuleName; + + } + + + public String getPendingServerRuleDisplayName() { + + return pendingServerRuleDisplayName; + + } + + public void setPendingServerRuleDisplayName( + String pendingServerRuleDisplayName + ) { + + this.pendingServerRuleDisplayName = + pendingServerRuleDisplayName; + + } + + + public String getPendingServerRuleLore( + int index + ) { + + return pendingServerRuleLore[index]; + + } + + public void setPendingServerRuleLore( + int index, + String value + ) { + + pendingServerRuleLore[index] = + value; + + } + + public void clearPendingServerRuleLore() { + + for ( + int i = 0; + i < pendingServerRuleLore.length; + i++ + ) { + + pendingServerRuleLore[i] = + null; + + } + + } + + + public int getPendingServerRuleLoreSlot() { + + return pendingServerRuleLoreSlot; + + } + + public void setPendingServerRuleLoreSlot( + int pendingServerRuleLoreSlot + ) { + + this.pendingServerRuleLoreSlot = + pendingServerRuleLoreSlot; + + } + + + public long getPendingServerRuleLoreExpiration() { + + return pendingServerRuleLoreExpiration; + + } + + public void setPendingServerRuleLoreExpiration( + long pendingServerRuleLoreExpiration + ) { + + this.pendingServerRuleLoreExpiration = + pendingServerRuleLoreExpiration; + + } + + + public String getPendingServerRuleMaterial() { + + return pendingServerRuleMaterial; + + } + + public void setPendingServerRuleMaterial( + String pendingServerRuleMaterial + ) { + + this.pendingServerRuleMaterial = + pendingServerRuleMaterial; + + } + +} \ No newline at end of file diff --git a/src/main/java/com/rsscripting/rswarehouse/session/admin/ServerRuleCreationSessionManager.java b/src/main/java/com/rsscripting/rswarehouse/session/admin/ServerRuleCreationSessionManager.java new file mode 100644 index 0000000..c60d163 --- /dev/null +++ b/src/main/java/com/rsscripting/rswarehouse/session/admin/ServerRuleCreationSessionManager.java @@ -0,0 +1,46 @@ +package com.rsscripting.rswarehouse.session.admin; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class ServerRuleCreationSessionManager { + + private static final Map sessions = + new HashMap<>(); + + + public static void createSession( + UUID uuid + ) { + + sessions.put( + uuid, + new ServerRuleCreationSession() + ); + + } + + + public static ServerRuleCreationSession getSession( + UUID uuid + ) { + + return sessions.get( + uuid + ); + + } + + + public static void removeSession( + UUID uuid + ) { + + sessions.remove( + uuid + ); + + } + +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 9bb0df7..242b1d0 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -13,6 +13,11 @@ display: # execute any commands. show-server-commands: true + # Display the Server Rules category. + # This category is a list of rules for + # your server. + show-server-rules: true + ############################################ # Automatic-Chest scan and process settings. ############################################