diff --git a/pom.xml b/pom.xml index afb785b..9733dd3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.mcmiddleearth MCME-Architect - 2.9.14 + 2.9.15 jar UTF-8 diff --git a/src/main/java/com/mcmiddleearth/architect/ArchitectPlugin.java b/src/main/java/com/mcmiddleearth/architect/ArchitectPlugin.java index 088a337..49f2804 100644 --- a/src/main/java/com/mcmiddleearth/architect/ArchitectPlugin.java +++ b/src/main/java/com/mcmiddleearth/architect/ArchitectPlugin.java @@ -32,6 +32,7 @@ import com.mcmiddleearth.architect.specialBlockHandling.command.GetCommand; import com.mcmiddleearth.architect.specialBlockHandling.command.InvCommand; import com.mcmiddleearth.architect.specialBlockHandling.command.SwitchStickCommand; +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.CustomInventoryEditor; import com.mcmiddleearth.architect.specialBlockHandling.data.*; import com.mcmiddleearth.architect.specialBlockHandling.itemBlock.ItemBlockCommand; import com.mcmiddleearth.architect.specialBlockHandling.itemBlock.ItemBlockListener; @@ -146,7 +147,8 @@ public void onEnable() { setCommandExecutor("switchstick", new SwitchStickCommand()); //setCommandExecutor("speed", new SpeedCommand()); // setCommandExecutor("newafkk", new NewAfkCommand()); - + + CustomInventoryEditor.init(this); rpSwitchTask = new RPSwitchTask().runTaskTimer(this, 500, 20); ItemBlockManager.startEntityGlowTask(); diff --git a/src/main/java/com/mcmiddleearth/architect/Permission.java b/src/main/java/com/mcmiddleearth/architect/Permission.java index cb45f9c..ae9640c 100644 --- a/src/main/java/com/mcmiddleearth/architect/Permission.java +++ b/src/main/java/com/mcmiddleearth/architect/Permission.java @@ -63,6 +63,7 @@ public enum Permission { INV_COMMAND ("architect.inventory"), INV_OTHER ("architect.inventory.other"), INV_SAVE ("architect.inventory.save"), + INV_EDIT ("architect.inventory.edit"), INV_RELOAD_COMMAND ("architect.inventory.reload"), INVENTORY_OPEN ("architect.inventory.open"), NO_PHYSICS_LIST ("architect.noPhysicsList.view"), diff --git a/src/main/java/com/mcmiddleearth/architect/serverResoucePack/RpManager.java b/src/main/java/com/mcmiddleearth/architect/serverResoucePack/RpManager.java index 28ac4bb..41162b1 100644 --- a/src/main/java/com/mcmiddleearth/architect/serverResoucePack/RpManager.java +++ b/src/main/java/com/mcmiddleearth/architect/serverResoucePack/RpManager.java @@ -29,6 +29,7 @@ import com.mcmiddleearth.connect.log.Log; import com.mcmiddleearth.util.DevUtil; import com.mcmiddleearth.util.ResourceUtil; +import com.viaversion.viaversion.api.Via; import org.bukkit.Location; import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; @@ -213,6 +214,9 @@ private static ConfigurationSection getConfigSection(String rp, Player player) { RpPlayerData data; if (player != null) { data = getPlayerData(player); + if(data.getProtocolVersion()==0) { + data.setProtocolVersion(Via.getAPI().getPlayerProtocolVersion(player.getUniqueId()).getVersion()); + } } else { data = new RpPlayerData(); } @@ -344,6 +348,7 @@ public static boolean setRp(String rpName, Player player, boolean force) { RpPlayerData data = getPlayerData(player); if(url!=null && data!=null && !url.equals("") && (force || !url.equals(data.getCurrentRpUrl()))) { data.setCurrentRpUrl(url); +//Logger.getGlobal().info("Sending to "+player.getName()+"("+getPlayerData(player).getProtocolVersion()+") RP: "+url); player.setResourcePack(url, getSHA(rpName, player)); savePlayerData(player); return true; diff --git a/src/main/java/com/mcmiddleearth/architect/serverResoucePack/RpPluginMessageListener.java b/src/main/java/com/mcmiddleearth/architect/serverResoucePack/RpPluginMessageListener.java index 2082a4c..af6abd2 100644 --- a/src/main/java/com/mcmiddleearth/architect/serverResoucePack/RpPluginMessageListener.java +++ b/src/main/java/com/mcmiddleearth/architect/serverResoucePack/RpPluginMessageListener.java @@ -16,8 +16,8 @@ public class RpPluginMessageListener implements PluginMessageListener { public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte[] bytes) { //Logger.getGlobal().info("Sodium client detected: "+player.getName()); -Logger.getGlobal().info("Received message from player " + player.getName() + " on channel " - + channel + " with data " + Arrays.toString(bytes)); +//Logger.getGlobal().info("Received message from player " + player.getName() + " on channel " +// + channel + " with data " + Arrays.toString(bytes)); try (var dataStream = new DataInputStream(new ByteArrayInputStream(bytes))) { int stringLength = readVarInt(dataStream); String jsonString = new String(dataStream.readNBytes(stringLength)); diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventory.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventory.java index 4d9431a..b2d2749 100644 --- a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventory.java +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventory.java @@ -22,9 +22,13 @@ */ import com.mcmiddleearth.architect.ArchitectPlugin; +import com.mcmiddleearth.architect.Permission; +import com.mcmiddleearth.architect.serverResoucePack.RpManager; +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.CustomInventoryEditor; import com.mcmiddleearth.architect.specialBlockHandling.data.SpecialBlockInventoryData; import com.mcmiddleearth.architect.specialBlockHandling.data.SpecialHeadInventoryData; import com.mcmiddleearth.architect.specialBlockHandling.data.SpecialItemInventoryData; +import com.mcmiddleearth.architect.specialBlockHandling.specialBlocks.SpecialBlock; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -339,6 +343,28 @@ void onCategoryChange(final InventoryClickEvent event) { } } } + + @EventHandler(priority = EventPriority.HIGHEST) + void onInventoryEdit(final InventoryClickEvent event) { + if (openInventories.containsKey(event.getInventory())) { //.getTitle.equals(name)) { + if (event.getWhoClicked() instanceof Player player + && player.hasPermission(Permission.INV_EDIT.getPermissionNode()) + && event.getRawSlot() >= CATEGORY_SLOTS + && event.getRawSlot() < event.getInventory().getSize() + && event.isRightClick() + && event.isShiftClick()) {//items.size()/9+1)*9 + CustomInventoryState state = openInventories.get(event.getInventory()); + String category = state.categoryNames[state.currentCategory]; + String rpName = RpManager.getCurrentRpName(state.getPlayer()); + event.getInventory().close(); + if(event.getCurrentItem() == null) { + CustomInventoryEditor.addBlock(player, rpName, category, state, event.getRawSlot()); + } else { + CustomInventoryEditor.editBlock(player, category, state, event.getRawSlot(), event.getCurrentItem()); + } + } + } + } @EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true) void onClose(final InventoryCloseEvent event) { diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventoryCategory.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventoryCategory.java index cbcc511..f8c2897 100644 --- a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventoryCategory.java +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventoryCategory.java @@ -21,6 +21,7 @@ import org.bukkit.inventory.ItemStack; import java.util.*; +import java.util.logging.Logger; /** * @@ -85,7 +86,10 @@ public boolean isVisible(Player player) { } public ItemStack getItem(String id) { - return items.stream().filter(item -> SpecialBlockInventoryData.getSpecialBlockId(item).equals(id)).findAny().orElse(null); + return items.stream().filter(item -> { + String blockId = SpecialBlockInventoryData.getSpecialBlockId(item); + return blockId != null && blockId.equals(id); + }).findAny().orElse(null); } public boolean isPublic() { diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventoryCollectionState.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventoryCollectionState.java index ed75f94..d9ccd54 100644 --- a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventoryCollectionState.java +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventoryCollectionState.java @@ -28,6 +28,7 @@ import org.bukkit.inventory.meta.ItemMeta; import java.util.*; +import java.util.logging.Logger; /** * @@ -212,4 +213,8 @@ public boolean isDirectGet() { public void setDirectGet(boolean directGet) { this.directGet = directGet; } + + public SpecialBlock getBaseBlock() { + return baseBlock; + } } \ No newline at end of file diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventoryState.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventoryState.java index fb7ecc3..262d6f2 100644 --- a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventoryState.java +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/CustomInventoryState.java @@ -281,4 +281,8 @@ public static ItemStack newPagingItem(Material material, int cmd, String display } public abstract boolean usesSubcategories(); + + public Player getPlayer() { + return player; + } } \ No newline at end of file diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/SearchInventory.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/SearchInventory.java index 8992aa3..048fa89 100644 --- a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/SearchInventory.java +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/SearchInventory.java @@ -222,7 +222,14 @@ public boolean isEmpty() { public ItemStack getItem(String id) { //Logger.getGlobal().info("search getItem: "+id); - return items.stream().filter(item -> item.getItemMeta().getLore().get(1).equals(id)).findFirst().orElse(null); + return items.stream().filter(item -> { + if(item.hasItemMeta() && item.getItemMeta().hasLore()) { + return item.getItemMeta().getLore().get(1).equals(id); +// } else { +// Logger.getGlobal().warning("Invalid item in search inventory: "+item); + } + return false; + }).findFirst().orElse(null); } public Set getRecipeKeys() { diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/CustomInventoryEditor.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/CustomInventoryEditor.java new file mode 100644 index 0000000..4ffecdb --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/CustomInventoryEditor.java @@ -0,0 +1,235 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor; + +import com.mcmiddleearth.architect.PluginData; +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.CustomInventory; +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.CustomInventoryCollectionState; +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.CustomInventoryState; +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add.BlockIdPrompt; +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.edit.EditPrompt; +import com.mcmiddleearth.architect.specialBlockHandling.data.SpecialBlockInventoryData; +import com.mcmiddleearth.architect.specialBlockHandling.specialBlocks.SpecialBlock; +import org.bukkit.ChatColor; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.conversations.*; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.logging.Logger; + +public class CustomInventoryEditor { + + private static ConversationFactory addBlockConversationFactory; + private static ConversationFactory editBlockConversationFactory; + + public static void init(Plugin plugin) { + Map sessionData = new HashMap<>(); + sessionData.put("blockData", new HashMap()); + addBlockConversationFactory = new ConversationFactory(plugin) + .withModality(false) + .withEscapeSequence("!cancel") + .withTimeout(300) + .withLocalEcho(true) + .withPrefix(conversationContext -> ChatColor.AQUA+"[Inventory Editor] ") + .withInitialSessionData(sessionData) + .addConversationAbandonedListener(new EditExecutor()) + .withFirstPrompt(new BlockIdPrompt()); + editBlockConversationFactory = new ConversationFactory(plugin) + .withModality(false) + .withEscapeSequence("!cancel") + .withTimeout(300) + .withLocalEcho(true) + .withPrefix(conversationContext -> ChatColor.AQUA+"[Inventory Editor] ") + .withInitialSessionData(sessionData) + .addConversationAbandonedListener(new EditExecutor()) + .withFirstPrompt(new EditPrompt()); + } + + public static void addBlock(Player player, String rpName, String category, CustomInventoryState state, int slot) { + Conversation conversation = addBlockConversationFactory.buildConversation(player); + ConversationContext context = conversation.getContext(); + context.setSessionData("rpName",rpName); + context.setSessionData("category", category); + context.setSessionData("state", state); + context.setSessionData("inCategory", true); + context.setSessionData("slot", getLocator(slot)); + conversation.begin(); + } + + @SuppressWarnings("unchecked") + public static void editBlock(Player player, String category, CustomInventoryState state, int slot, ItemStack inventoryItem) { + Conversation conversation = editBlockConversationFactory.buildConversation(player); + ConversationContext context = conversation.getContext(); + context.setSessionData("category", category); + context.setSessionData("state", state); + String[] rpAndId = SpecialBlockInventoryData.getSpecialBlockId(inventoryItem).split("/"); + context.setSessionData("id", rpAndId[1]); + context.setSessionData("rpName",rpAndId[0]); + ConfigurationSection inventoryConfig = getInventoryConfig(rpAndId[0], category); + assert inventoryConfig != null; + ConfigurationSection itemSection = inventoryConfig.getConfigurationSection(rpAndId[1]); + assert itemSection != null; + context.setSessionData("display", itemSection.get("display")); + context.setSessionData("type", itemSection.get("type")); + context.setSessionData("itemMaterial", itemSection.get("itemMaterial")); + if(itemSection.contains("cmd")) { + context.setSessionData("cmd", itemSection.get("cmd")); + } + if(itemSection.contains("color")) { + context.setSessionData("color", itemSection.get("color")); + } + context.setSessionData("inCategory", itemSection.contains("category")); + context.setSessionData("slot", getLocator(slot)); + Map blockData = (Map) context.getSessionData("blockData"); + assert blockData!=null; + itemSection.getKeys(false).stream().filter(key->key.startsWith("blockData")).forEach(key -> { + blockData.put(key.substring(9),itemSection.getString(key)); + }); + conversation.begin(); + } + + @SuppressWarnings("unchecked") + public static class EditExecutor implements ConversationAbandonedListener { + @Override + public void conversationAbandoned(@NotNull ConversationAbandonedEvent conversationAbandonedEvent) { + Player player = (Player) conversationAbandonedEvent.getContext().getForWhom(); + if(conversationAbandonedEvent.gracefulExit()) { + ConversationContext context = conversationAbandonedEvent.getContext(); + String rpName = (String) Objects.requireNonNull(context.getSessionData("rpName")); + File rpFolder = new File(SpecialBlockInventoryData.configFolder,rpName); + String category = (String) context.getSessionData("category"); assert category != null; + File categoryFile = new File(rpFolder, category.toLowerCase()+".yml"); + if(categoryFile.exists()) { + YamlConfiguration config = new YamlConfiguration(); + try { + config.load(categoryFile); + ConfigurationSection items = config.getConfigurationSection("Items"); + assert items != null; + if(context.getSessionData("oldId")!=null) { + String oldId = (String) Objects.requireNonNull(context.getSessionData("oldId")); + if(items.contains(oldId)) { + items.set(oldId, null); + } + } + String blockId = (String) Objects.requireNonNull(context.getSessionData("id")); + if("delete".equalsIgnoreCase((String) context.getSessionData("action"))) { + items.set(blockId, null); + } else { + ConfigurationSection newSection = items.createSection(blockId); + newSection.set("display", context.getSessionData("display")); + newSection.set("type", Objects.requireNonNull(context.getSessionData("type")).toString() + .toUpperCase()); + newSection.set("itemMaterial", context.getSessionData("itemMaterial")); + if ((context.getSessionData("cmd") != null)) { + newSection.set("cmd", context.getSessionData("cmd")); + } + if ((context.getSessionData("color") != null)) { + newSection.set("color", context.getSessionData("color")); + } + Object inCategory = context.getSessionData("inCategory"); + assert inCategory != null; + if ((Boolean) inCategory) { + newSection.set("category", context.getSessionData("category")); + } + if (context.getSessionData("state") instanceof CustomInventoryCollectionState collection) { + SpecialBlock baseBlock = collection.getBaseBlock(); + String baseId = baseBlock.getId().substring(baseBlock.getId().indexOf("/") + 1); + Logger.getGlobal().info("BaseId: " + baseId); + ConfigurationSection baseSection = items.getConfigurationSection(baseId); + assert baseSection != null; + ConfigurationSection collectionSection = baseSection.getConfigurationSection("collection"); + assert collectionSection != null; + String slot = (String) context.getSessionData("slot"); + assert slot != null; + if (context.getSessionData("oldSlot") != null) { + String oldSlot = (String) context.getSessionData("oldSlot"); + assert oldSlot != null; + String otherBlockId = collectionSection.getString(slot); + collectionSection.set(oldSlot, otherBlockId); + } + collectionSection.set(slot, blockId); + } + + Map blockData = (Map) context.getSessionData("blockData"); + assert blockData != null; + for (Map.Entry entry : blockData.entrySet()) { + newSection.set("blockData" + entry.getKey(), entry.getValue()); + } + } + config.save(categoryFile); + PluginData.getMessageUtil().sendInfoMessage(player, "Custom inventory item saved to file " + +rpName+"/"+categoryFile.getName()+" Reloading inventories..."); + SpecialBlockInventoryData.loadInventories(); + PluginData.getMessageUtil().sendInfoMessage(player, "Inventory reload done!"); + } catch (IOException | InvalidConfigurationException e) { + PluginData.getMessageUtil().sendErrorMessage(player, "Internal error" + + " while saving custom inventory."); + e.printStackTrace(); + } + } else { + PluginData.getMessageUtil().sendErrorMessage(player, + "Can't save custom inventory. Inventory config file not found: " + +rpName+"/"+categoryFile.getName()); + Logger.getGlobal().warning("Not found! "+categoryFile); + } + } else { + PluginData.getMessageUtil().sendErrorMessage(player, "Custom inventory editor conversation cancelled."); + } + } + } + + private static String getLocator(int slot) { + slot = slot - CustomInventory.CATEGORY_SLOTS; + char letter; + int number; + if(slot % 9 < 5) { + letter = switch (slot / 9) { + case 0 -> 'A'; + case 1 -> 'B'; + case 2 -> 'C'; + case 3 -> 'D'; + case 4 -> 'E'; + default -> 'X'; + }; + number = 4 - slot % 9; + } else { + letter = switch (slot / 9) { + case 0 -> 'F'; + case 1 -> 'G'; + case 2 -> 'H'; + case 3 -> 'I'; + case 4 -> 'J'; + default -> 'X'; + }; + number = slot % 9 - 4; + } + return ""+letter+number; + } + + private static ConfigurationSection getInventoryConfig(String rpName, String category) { + File rpFolder = new File(SpecialBlockInventoryData.configFolder, rpName); + File categoryFile = new File(rpFolder, category.toLowerCase() + ".yml"); + if (categoryFile.exists()) { + YamlConfiguration config = new YamlConfiguration(); + try { + config.load(categoryFile); + return config.getConfigurationSection("Items"); + } catch (IOException | InvalidConfigurationException e) { + Logger.getGlobal().warning("Error while reading inventory config! " + categoryFile); + e.printStackTrace(); + return null; + } + } else { + Logger.getGlobal().warning("Not found! " + categoryFile); + return null; + } + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/BlockDataPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/BlockDataPrompt.java new file mode 100644 index 0000000..c79d77d --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/BlockDataPrompt.java @@ -0,0 +1,100 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add; + +import com.mcmiddleearth.architect.ArchitectPlugin; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.Prompt; +import org.bukkit.conversations.ValidatingPrompt; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.Map; +import java.util.Objects; +import java.util.logging.Logger; + +public class BlockDataPrompt extends ValidatingPrompt implements Listener { + private boolean listenerRegistered = false; + + private ConversationContext conversationContext; + + private final String[] blockStateKeys; + + public BlockDataPrompt(String... blockStateKeys) { + this.blockStateKeys = blockStateKeys; + } + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "Left-click a block to use for blockData"+blockStateKeys[0]+". You may also type in valid block data."; + } + + @Override + protected @Nullable String getFailedValidationText(@NotNull ConversationContext context, @NotNull String invalidInput) { + return "You need to left-click a block or type in valid block data!"; + } + + @Override + public boolean blocksForInput(@NotNull ConversationContext conversationContext) { + if(!listenerRegistered) { + this.conversationContext = conversationContext; + Bukkit.getPluginManager().registerEvents(this, Objects.requireNonNull(conversationContext.getPlugin())); + listenerRegistered = true; + } + return true; + } + + @Override + protected boolean isInputValid(@NotNull ConversationContext conversationContext, @NotNull String input) { + try { + Bukkit.createBlockData(input); + return true; + } catch(IllegalArgumentException ignore){} + return false; + } + + @Override + @SuppressWarnings("unchecked") + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + HandlerList.unregisterAll(this); + Map blockDatas = (Map) Objects.requireNonNull(conversationContext.getSessionData("blockData")); + blockDatas.put(blockStateKeys[0], input); + if(blockStateKeys.length>1) { + return new BlockDataPrompt(Arrays.copyOfRange(blockStateKeys,1,blockStateKeys.length)); + } else { + return new ItemPrompt(); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onSelectBlockstate(PlayerInteractEvent event) { +Logger.getGlobal().info("onSelectBlockstate"); + if(event.getPlayer().equals(conversationContext.getForWhom()) && event.getAction().equals(Action.LEFT_CLICK_BLOCK) + && event.getHand()!=null && event.getHand().equals(EquipmentSlot.HAND) + && event.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.PRISMARINE_SHARD)) { + Block block = event.getClickedBlock(); +Logger.getGlobal().info("Block: "+block); + if(block != null) { +Logger.getGlobal().info("BlockData: "+block.getBlockData()); + HandlerList.unregisterAll(this); + event.setCancelled(true); + Bukkit.getScheduler().runTaskLater(ArchitectPlugin.getPluginInstance(),()-> { + conversationContext.getForWhom().acceptConversationInput(block.getBlockData().getAsString()); + }, 3); + } + } + } + + protected String[] getBlockStateKeys() { + return blockStateKeys; + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/BlockIdPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/BlockIdPrompt.java new file mode 100644 index 0000000..2fba69d --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/BlockIdPrompt.java @@ -0,0 +1,33 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add; + +import com.mcmiddleearth.architect.specialBlockHandling.data.SpecialBlockInventoryData; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.Prompt; +import org.bukkit.conversations.ValidatingPrompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class BlockIdPrompt extends ValidatingPrompt { + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "Type in an unique ID for the new item! You may '!cancel' at any point of the conversation."; + } + + @Override + protected @Nullable String getFailedValidationText(@NotNull ConversationContext context, @NotNull String invalidInput) { + return "You need to type in an item id that doesn't exist yet."; + } + + @Override + protected boolean isInputValid(@NotNull ConversationContext conversationContext, @NotNull String input) { + return SpecialBlockInventoryData.getSpecialBlock(conversationContext.getSessionData("rpName")+"/"+input) + == null; + } + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + conversationContext.setSessionData("id", input); + return new BlockTypePrompt(); + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/BlockTypePrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/BlockTypePrompt.java new file mode 100644 index 0000000..5968751 --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/BlockTypePrompt.java @@ -0,0 +1,72 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add; + +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.FixedSetPrompt; +import org.bukkit.conversations.Prompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; + +public class BlockTypePrompt extends FixedSetPrompt { + + public static final String[][] blockData = new String[][]{ + {"block", ""}, + {"bisected", "Up", "Down"}, + {"four_directions", "North", "West", "South", "East"}, + {"six_faces", "North", "West", "South", "East", "Up", "Down"}, + {"five_faces", "North", "West", "South", "East", "Up"}, + {"three_axis", "X", "Y", "Z"}, + {"branch_twigs",}, + {"branch_horizontal",}, + {"diagonal_connect", "North", "West", "South", "East", "Up" }, + {"block_connect",""}, + {"double_y_block","Upper", "Lower"}, + {"eight_faces", "North", "NorthWest", "West", "SouthWest", "South", "SouthEast", "East", "NorthEast"}, + {"upshift",""}, + {"block_on_water",""}, + {"vanilla"} + }; + + public BlockTypePrompt() { + super(getBlockTypes()); + } + + protected BlockTypePrompt(@NotNull String... fixedSet) { + super(fixedSet); + } + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + conversationContext.setSessionData("type",input); + for (String[] blockDatum : blockData) { + if (input.equalsIgnoreCase(blockDatum[0])) { + String[] blockOrientations = Arrays.copyOfRange(blockDatum, 1, blockDatum.length); + if(blockOrientations.length == 0) { + return new ItemPrompt(); + } else { + return new BlockDataPrompt(blockOrientations); + } + } + } + return END_OF_CONVERSATION; + } + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "Which type of block do you want to add? "+formatFixedSet()+" "; + } + + @Override + protected @Nullable String getFailedValidationText(@NotNull ConversationContext context, @NotNull String invalidInput) { + return "Not all block types are supported. You need to type in one of the listed block types."; + } + + public static String[] getBlockTypes() { + String[] result = new String[blockData.length]; + for(int i = 0; i < blockData.length; i++) { + result[i] = blockData[i][0]; + } + return result; + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/CategoryVisiblePrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/CategoryVisiblePrompt.java new file mode 100644 index 0000000..fb9883c --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/CategoryVisiblePrompt.java @@ -0,0 +1,34 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add; + +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.FixedSetPrompt; +import org.bukkit.conversations.Prompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class CategoryVisiblePrompt extends FixedSetPrompt { + + public CategoryVisiblePrompt() { + super("yes", "no"); + } + + protected CategoryVisiblePrompt(@NotNull String... fixedSet) { + super(fixedSet); + } + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "Should the new inventory item be listed directly in the category of it's collection. "+formatFixedSet(); + } + + @Override + protected @Nullable String getFailedValidationText(@NotNull ConversationContext context, @NotNull String invalidInput) { + return "If you type in 'no' the item will be available only by a block collection."; + } + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + conversationContext.setSessionData("inCategory", input.equalsIgnoreCase("yes")); + return END_OF_CONVERSATION; + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/CmdPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/CmdPrompt.java new file mode 100644 index 0000000..8de75b9 --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/CmdPrompt.java @@ -0,0 +1,43 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add; + +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.edit.ChangeColorPrompt; +import com.mcmiddleearth.pluginutil.NumericUtil; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.Prompt; +import org.bukkit.conversations.ValidatingPrompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; + +public class CmdPrompt extends ValidatingPrompt { + + @Override + protected boolean isInputValid(@NotNull ConversationContext conversationContext, @NotNull String input) { + return input.equalsIgnoreCase("!skip") + || NumericUtil.isInt(input) && NumericUtil.getInt(input)>-1; + } + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + if(!input.equalsIgnoreCase("!skip")) { + conversationContext.setSessionData("cmd",NumericUtil.getInt(input)); + } + if(((String) Objects.requireNonNull(conversationContext.getSessionData("itemMaterial"))).startsWith("LEATHER")) { + return new ColorPrompt(); + } else { + return new DisplayPrompt(); + } + } + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "Current custom model data is "+conversationContext.getSessionData("cmd") + +". Type in a new custom model data or '!skip'"; + } + + @Override + protected @Nullable String getFailedValidationText(@NotNull ConversationContext context, @NotNull String invalidInput) { + return "You need to type in a not negative integer or '!skip'."; + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/ColorPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/ColorPrompt.java new file mode 100644 index 0000000..3a24bdd --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/ColorPrompt.java @@ -0,0 +1,35 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add; + +import com.mcmiddleearth.pluginutil.NumericUtil; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.Prompt; +import org.bukkit.conversations.ValidatingPrompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ColorPrompt extends ValidatingPrompt { + + @Override + protected boolean isInputValid(@NotNull ConversationContext conversationContext, @NotNull String input) { + return input.equalsIgnoreCase("!skip") + || NumericUtil.isInt(input) && NumericUtil.getInt(input)>-1; + } + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + if(!input.equalsIgnoreCase("!skip")) { + conversationContext.setSessionData("color", NumericUtil.getInt(input)); + } + return new DisplayPrompt(); + } + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "Current color is "+conversationContext.getSessionData("color")+". Type in a new color or '!skip'"; + } + + @Override + protected @Nullable String getFailedValidationText(@NotNull ConversationContext context, @NotNull String invalidInput) { + return "You need to type in a valid rgb color code."; + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/DisplayPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/DisplayPrompt.java new file mode 100644 index 0000000..763287e --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/DisplayPrompt.java @@ -0,0 +1,26 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add; + +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.CustomInventoryCollectionState; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.Prompt; +import org.bukkit.conversations.StringPrompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class DisplayPrompt extends StringPrompt { + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "Enter a description for the custom inventory:"; + } + + @Override + public @Nullable Prompt acceptInput(@NotNull ConversationContext conversationContext, @Nullable String input) { + conversationContext.setSessionData("display", input); + if(conversationContext.getSessionData("state") instanceof CustomInventoryCollectionState) { + return new CategoryVisiblePrompt(); + } else { + return END_OF_CONVERSATION; + } + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/ItemPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/ItemPrompt.java new file mode 100644 index 0000000..8546f03 --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/add/ItemPrompt.java @@ -0,0 +1,49 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add; + +import org.bukkit.Material; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.FixedSetPrompt; +import org.bukkit.conversations.Prompt; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ItemPrompt extends FixedSetPrompt { + + public ItemPrompt() { + super("ok"); + } + + protected ItemPrompt(String... fixedSet) { + super(fixedSet); + } + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + ItemStack item = ((Player)conversationContext.getForWhom()).getInventory().getItemInMainHand(); + conversationContext.setSessionData("itemMaterial", item.getType().name()); + if(item.hasItemMeta() && item.getItemMeta().hasCustomModelData()) { + conversationContext.setSessionData("cmd", item.getItemMeta().getCustomModelData()); + } + if(item.getType().name().startsWith("LEATHER")) { + LeatherArmorMeta meta = (LeatherArmorMeta) item.getItemMeta(); + conversationContext.setSessionData("color", meta.getColor().asRGB()); + } + return new CmdPrompt(); + } + + @Override + protected boolean isInputValid(@NotNull ConversationContext context, @NotNull String input) { + return !((Player)context.getForWhom()).getInventory().getItemInMainHand().getType().equals(Material.AIR) + && super.isInputValid(context, input); + + } + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "Hold the item you want to add to custom inventory in main hand and type 'ok'."; + } + +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeBlockDataPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeBlockDataPrompt.java new file mode 100644 index 0000000..0eaaaf9 --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeBlockDataPrompt.java @@ -0,0 +1,46 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.edit; + +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add.BlockDataPrompt; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.Prompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.Map; + +public class ChangeBlockDataPrompt extends BlockDataPrompt { + + public ChangeBlockDataPrompt(String... blockStateKeys) { + super(blockStateKeys); + } + + @Override + @SuppressWarnings("unchecked") + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + Map blockData = (Map) conversationContext.getSessionData("blockData"); + assert blockData != null; + return "Current blockData"+getBlockStateKeys()[0]+" is " + +blockData.get(getBlockStateKeys()[0])+". Left-click a block to use for blockData"+getBlockStateKeys()[0] + +". Or type '!skip'. You may also type in valid block data."; + } + + @Override + protected boolean isInputValid(@NotNull ConversationContext conversationContext, @NotNull String input) { + return input.equalsIgnoreCase("!skip") || super.isInputValid(conversationContext, input); + } + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + if (!input.equalsIgnoreCase("!skip")) { + super.acceptValidatedInput(conversationContext, input); + } + if(getBlockStateKeys().length>1) { + return new ChangeBlockDataPrompt(Arrays.copyOfRange(getBlockStateKeys(),1,getBlockStateKeys().length)); + } else { + return new ChangeItemPrompt(); + } + } + + +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeBlockIdPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeBlockIdPrompt.java new file mode 100644 index 0000000..0006dc6 --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeBlockIdPrompt.java @@ -0,0 +1,25 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.edit; + +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add.BlockIdPrompt; +import com.mcmiddleearth.architect.specialBlockHandling.data.SpecialBlockInventoryData; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.Prompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ChangeBlockIdPrompt extends BlockIdPrompt { + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "Current item id is "+conversationContext.getSessionData("id")+". Enter a new id or '!skip'."; + } + + @Override + public @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + if(!input.equalsIgnoreCase("!skip")) { + conversationContext.setSessionData("oldId", conversationContext.getSessionData("id")); + conversationContext.setSessionData("id",input); + } + return new ChangeBlockTypePrompt(); + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeBlockTypePrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeBlockTypePrompt.java new file mode 100644 index 0000000..a5218bb --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeBlockTypePrompt.java @@ -0,0 +1,48 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.edit; + +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add.BlockTypePrompt; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.FixedSetPrompt; +import org.bukkit.conversations.Prompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; + +public class ChangeBlockTypePrompt extends BlockTypePrompt { + + public ChangeBlockTypePrompt() { + super(getFixedSet()); + } + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + if(!input.equalsIgnoreCase("!skip")) { + conversationContext.setSessionData("type",input); + } + String type = (String) conversationContext.getSessionData("type"); assert type != null; + for (String[] blockDatum : BlockTypePrompt.blockData) { + if (type.equalsIgnoreCase(blockDatum[0])) { + String[] blockOrientations = Arrays.copyOfRange(blockDatum, 1, blockDatum.length); + if(blockOrientations.length == 0) { + return new ChangeItemPrompt(); + } else { + return new ChangeBlockDataPrompt(blockOrientations); + } + } + } + return END_OF_CONVERSATION; + } + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "Current block type is "+conversationContext.getSessionData("type") + +". Type in a new block type or '!skip' "+formatFixedSet(); + } + + private static String[] getFixedSet() { + String[] result = Arrays.copyOf(BlockTypePrompt.getBlockTypes(), BlockTypePrompt.getBlockTypes().length+1); + result[result.length-1] = "!skip"; + return result; + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeCategoryVisiblePrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeCategoryVisiblePrompt.java new file mode 100644 index 0000000..c9ad960 --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeCategoryVisiblePrompt.java @@ -0,0 +1,31 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.edit; + +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add.CategoryVisiblePrompt; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.Prompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ChangeCategoryVisiblePrompt extends CategoryVisiblePrompt { + + public ChangeCategoryVisiblePrompt() { + super(getFixedSet()); + } + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + if(!input.equalsIgnoreCase("!skip")) { + conversationContext.setSessionData("inCategory", input.equalsIgnoreCase("yes")); + } + return new ChangeSlotPrompt(); + } + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "Should the inventory item be listed directly in the category of it's collection? "+formatFixedSet(); + } + + private static String[] getFixedSet() { + return new String[]{"yes", "no", "!skip"}; + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeCmdPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeCmdPrompt.java new file mode 100644 index 0000000..2c1f1b0 --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeCmdPrompt.java @@ -0,0 +1,22 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.edit; + +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add.CmdPrompt; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.Prompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; + +public class ChangeCmdPrompt extends CmdPrompt { + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + super.acceptValidatedInput(conversationContext, input); + if(((String) Objects.requireNonNull(conversationContext.getSessionData("itemMaterial"))).startsWith("LEATHER")) { + return new ChangeColorPrompt(); + } else { + return new ChangeDisplayPrompt(); + } + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeColorPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeColorPrompt.java new file mode 100644 index 0000000..b5bc016 --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeColorPrompt.java @@ -0,0 +1,16 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.edit; + +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add.ColorPrompt; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.Prompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ChangeColorPrompt extends ColorPrompt { + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + super.acceptValidatedInput(conversationContext, input); + return new ChangeDisplayPrompt(); + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeDisplayPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeDisplayPrompt.java new file mode 100644 index 0000000..6ce93fa --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeDisplayPrompt.java @@ -0,0 +1,29 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.edit; + +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.CustomInventoryCollectionState; +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add.DisplayPrompt; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.Prompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ChangeDisplayPrompt extends DisplayPrompt { + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "Current description is "+conversationContext.getSessionData("display") + +". Type in new description for the custom inventory or type '!skip'."; + } + + @Override + public @Nullable Prompt acceptInput(@NotNull ConversationContext conversationContext, @Nullable String input) { + if(input != null && !input.equalsIgnoreCase("!skip")) { + conversationContext.setSessionData("display", input); + } + if(conversationContext.getSessionData("state") instanceof CustomInventoryCollectionState) { + return new ChangeCategoryVisiblePrompt(); + } else { + return END_OF_CONVERSATION; + } + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeItemPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeItemPrompt.java new file mode 100644 index 0000000..61354d5 --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeItemPrompt.java @@ -0,0 +1,46 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.edit; + +import com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.add.ItemPrompt; +import org.bukkit.Material; +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.Prompt; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ChangeItemPrompt extends ItemPrompt { + + public ChangeItemPrompt() { + super("ok", "!skip"); + } + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + if(!input.equalsIgnoreCase("!skip")) { + ItemStack item = ((Player)conversationContext.getForWhom()).getInventory().getItemInMainHand(); + conversationContext.setSessionData("itemMaterial", item.getType()); + if(item.hasItemMeta() && item.getItemMeta().hasCustomModelData()) { + conversationContext.setSessionData("cmd", item.getItemMeta().getCustomModelData()); + } + if(item.getType().name().startsWith("LEATHER")) { + LeatherArmorMeta meta = (LeatherArmorMeta) item.getItemMeta(); + conversationContext.setSessionData("color", meta.getColor().asRGB()); + } + } + return new ChangeCmdPrompt(); + } + + @Override + protected boolean isInputValid(@NotNull ConversationContext context, @NotNull String input) { + return !((Player)context.getForWhom()).getInventory().getItemInMainHand().getType().equals(Material.AIR) + && super.isInputValid(context, input) + || input.equalsIgnoreCase("!skip"); + } + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "To change the inventory item hold in main hand a new item and type 'ok'. To not change type '!skip'"; + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeSlotPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeSlotPrompt.java new file mode 100644 index 0000000..33820ab --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/ChangeSlotPrompt.java @@ -0,0 +1,35 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.edit; + +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.FixedSetPrompt; +import org.bukkit.conversations.Prompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ChangeSlotPrompt extends FixedSetPrompt { + + public ChangeSlotPrompt() { + super("A0", "A1", "A4", "B2", "B4", "C2", "C4", "D2", "D4", "E0", "E1", "E4", + "F1", "F4", "G2", "G4", "H2", "H4", "I2", "I4", "J1", "J4", "!skip"); + } + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + if(!input.equalsIgnoreCase("!skip")) { + conversationContext.setSessionData("oldSlot", conversationContext.getSessionData("slot")); + conversationContext.setSessionData("slot", input); + } + return END_OF_CONVERSATION; + } + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "Current item slot is "+conversationContext.getSessionData("slot") + +". Type in a new slot for the inventory item or '!skip'. "+formatFixedSet(); + } + + @Override + protected @Nullable String getFailedValidationText(@NotNull ConversationContext context, @NotNull String invalidInput) { + return "You need to type in a slot label or '!skip'."; + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/EditPrompt.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/EditPrompt.java new file mode 100644 index 0000000..d934dd8 --- /dev/null +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/customInventories/editor/prompt/edit/EditPrompt.java @@ -0,0 +1,34 @@ +package com.mcmiddleearth.architect.specialBlockHandling.customInventories.editor.prompt.edit; + +import org.bukkit.conversations.ConversationContext; +import org.bukkit.conversations.FixedSetPrompt; +import org.bukkit.conversations.Prompt; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class EditPrompt extends FixedSetPrompt { + + public EditPrompt() { + super("edit", "delete"); + } + + @Override + protected @Nullable Prompt acceptValidatedInput(@NotNull ConversationContext conversationContext, @NotNull String input) { + conversationContext.setSessionData("action",input); + if(input.equalsIgnoreCase("edit")) { + return new ChangeBlockIdPrompt(); + } else { + return END_OF_CONVERSATION; + } + } + + @Override + public @NotNull String getPromptText(@NotNull ConversationContext conversationContext) { + return "What do you want to do with inventory item "+conversationContext.getSessionData("id")+"? "+formatFixedSet(); + } + + @Override + protected @Nullable String getFailedValidationText(@NotNull ConversationContext context, @NotNull String invalidInput) { + return "You need to type in 'edit' or 'delete'. Or you may '!cancel' at any point of the conversation."; + } +} diff --git a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/data/SpecialBlockInventoryData.java b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/data/SpecialBlockInventoryData.java index 82d2d72..18b8e12 100644 --- a/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/data/SpecialBlockInventoryData.java +++ b/src/main/java/com/mcmiddleearth/architect/specialBlockHandling/data/SpecialBlockInventoryData.java @@ -62,7 +62,7 @@ public class SpecialBlockInventoryData { private static final String configLocator = "inventories"; - private static final File configFolder = new File(ArchitectPlugin.getPluginInstance() + public static final File configFolder = new File(ArchitectPlugin.getPluginInstance() .getDataFolder(),configLocator+"/block"); static { diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 2740e2f..d87ca2a 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -119,6 +119,7 @@ permissions: architect.bannerEditor.delete: true architect.inventory.reload: true architect.inventory.other: true + architect.inventory.edit: true architect.get.other: true architect.weather: true archtiect.resourcePackAdmin: true @@ -396,8 +397,11 @@ permissions: descriptions: Allows to check item NBTs default: op architect.inventory.ignoreProtection: - descriptions: Allows to edit inventory content without build permission - default: op + descriptions: Allows to edit inventory content without build permission + default: op + architect.inventory.edit: + descriptions: Allows to edit custom inventory + default: op architect.viewdistance: descriptions: Allows to change client view distance default: op \ No newline at end of file