From 081266accf95a49c3af4290dfdbc2b899b25a735 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Sat, 30 Mar 2024 21:20:12 +0100 Subject: [PATCH] Add create conflict item. --- .../gui/config/global/EnchantConflictGui.java | 91 +++++++++++++++++-- src/main/kotlin/io/delilaheve/CustomAnvil.kt | 12 ++- .../cuanvil/command/ReloadExecutor.kt | 1 + .../cuanvil/group/EnchantConflictManager.kt | 18 +--- .../cuanvil/listener/ChatEventListener.kt | 47 ++++++++++ 5 files changed, 147 insertions(+), 22 deletions(-) create mode 100644 src/main/kotlin/xyz/alexcrea/cuanvil/listener/ChatEventListener.kt diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java index 802301e..2f9ff19 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantConflictGui.java @@ -9,6 +9,7 @@ import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import io.delilaheve.CustomAnvil; import org.bukkit.Material; +import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.HumanEntity; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; @@ -16,16 +17,16 @@ import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.group.EnchantConflictGroup; +import xyz.alexcrea.cuanvil.group.IncludeGroup; import xyz.alexcrea.cuanvil.gui.config.settings.subsetting.EnchantConflictSubSettingGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.util.CasedStringUtil; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.UUID; +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; public class EnchantConflictGui extends ChestGui { @@ -62,7 +63,6 @@ public class EnchantConflictGui extends ChestGui { GuiGlobalItems.addBackgroundItem(this.backgroundPane); this.backgroundPane.bindItem('1', GuiSharedConstant.SECONDARY_BACKGROUND_ITEM); - this.backgroundPane.bindItem('C', GuiSharedConstant.SECONDARY_BACKGROUND_ITEM); addPane(this.backgroundPane); // Page init @@ -112,6 +112,85 @@ public class EnchantConflictGui extends ChestGui { viewer.setItemOnCursor(cursor); }, CustomAnvil.instance); + // Create new conflict item + ItemStack createItem = new ItemStack(Material.GREEN_TERRACOTTA); + ItemMeta createMeta = createItem.getItemMeta(); + + createItem.setItemMeta(createMeta); + + this.backgroundPane.bindItem('C', new GuiItem(createItem, (clickEvent)->{ + clickEvent.setCancelled(true); + HumanEntity player = clickEvent.getWhoClicked(); + + // check permission + if(!player.hasPermission(CustomAnvil.editConfigPermission)) { + player.closeInventory(); + player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); + return; + } + player.closeInventory(); + + player.sendMessage("\u00A7eWrite the conflict you want to create in the chat.\n" + + "\u00A7eOr write \u00A7ccancel \u00A7eto go back to conflict config menu"); + + CustomAnvil.Companion.getChatListener().setListenedCallback(player, prepareCreateItemConsumer(player)); + + }, CustomAnvil.instance)); + } + + private Consumer prepareCreateItemConsumer(HumanEntity player) { + AtomicReference> selfRef = new AtomicReference<>(); + Consumer selfCallback = (message) -> { + if(message == null) return; + + message = message.toLowerCase(Locale.ROOT); + if("cancel".equalsIgnoreCase(message)) { + player.sendMessage("cancelled..."); + show(player); + return; + } + + message = message.replace('_', ' '); + + // Try to find if it already exists in a for loop + // Not the most efficient on large number of conflict, but it should not run often. + for (EnchantConflictGroup conflict : ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList()) { + if(conflict.getName().equalsIgnoreCase(message)){ + player.sendMessage("\u00A7cPlease enter a conflict name that do not already exist..."); + // wait next message. + CustomAnvil.Companion.getChatListener().setListenedCallback(player, selfRef.get()); + return; + } + } + + // Create new empty conflict and display it to the admin + EnchantConflictGroup conflict = new EnchantConflictGroup( + message, + new IncludeGroup("new_group"), + 0); + + ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList().add(conflict); + updateValueForConflict(conflict, true); + + // save empty conflict in config + String[] emptyStringArray = new String[0]; + + FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig(); + config.set(message+".enchantments", emptyStringArray); + config.set(message+".notAffectedGroups", emptyStringArray); + config.set(message+".maxEnchantmentBeforeConflict", 0); + + if(GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE){ + ConfigHolder.CONFLICT_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE); + } + + // show the new conflict config to the player + this.conflictGuiMap.get(conflict).show(player); + + }; + + selfRef.set(selfCallback); + return selfCallback; } private OutlinePane createEmptyPage(){ @@ -136,7 +215,7 @@ public class EnchantConflictGui extends ChestGui { update(); } - public ItemStack createItemForConflict(EnchantConflictGroup conflict){ + public static ItemStack createItemForConflict(EnchantConflictGroup conflict){ ItemStack item = new ItemStack(conflict.getRepresentativeMaterial()); ItemMeta meta = item.getItemMeta(); diff --git a/src/main/kotlin/io/delilaheve/CustomAnvil.kt b/src/main/kotlin/io/delilaheve/CustomAnvil.kt index 28c8dd0..532b4a7 100644 --- a/src/main/kotlin/io/delilaheve/CustomAnvil.kt +++ b/src/main/kotlin/io/delilaheve/CustomAnvil.kt @@ -7,14 +7,14 @@ import org.bukkit.plugin.java.JavaPlugin import xyz.alexcrea.cuanvil.command.EditConfigExecutor import xyz.alexcrea.cuanvil.command.ReloadExecutor import xyz.alexcrea.cuanvil.config.ConfigHolder +import xyz.alexcrea.cuanvil.listener.ChatEventListener import xyz.alexcrea.cuanvil.util.Metrics import xyz.alexcrea.cuanvil.util.MetricsUtil import java.io.File import java.io.FileReader /** - * Bukkit/Spigot/Paper plugin to alter enchantment max - * levels and allow unsafe enchantment combinations + * Bukkit/Spigot/Paper plugin to alter anvil feature */ class CustomAnvil : JavaPlugin() { @@ -41,6 +41,9 @@ class CustomAnvil : JavaPlugin() { // Current plugin instance lateinit var instance: CustomAnvil + // Chat message listener + lateinit var chatListener: ChatEventListener + /** * Logging handler */ @@ -74,8 +77,11 @@ class CustomAnvil : JavaPlugin() { logger.warning("Please note CustomAnvil is a more recent version of UnsafeEnchantsPlus") } - // Load config + // Load chat listener + chatListener = ChatEventListener() + Bukkit.getPluginManager().registerEvents(chatListener, this) + // Load config val success = ConfigHolder.loadConfig() if(!success) return diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt index 936127e..ce864ab 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt @@ -41,6 +41,7 @@ class ReloadExecutor : CommandExecutor { BasicConfigGui.INSTANCE.updateGuiValues() EnchantCostConfigGui.INSTANCE.updateGuiValues() EnchantLimitConfigGui.INSTANCE.updateGuiValues() + EnchantCostConfigGui.INSTANCE.updateGuiValues() // & update metric MetricsUtil.testIfConfigIsDefault() diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt index 3d6eb29..633e49c 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt @@ -18,8 +18,6 @@ class EnchantConflictManager { // Path for a flag: if the enchantment will be used in the last supported version // TODO maybe replace this system by a list of "future" enchantment. private const val FUTURE_USE_PATH = "useInFuture" - // Default name for an empty Material group - private val DEFAULT_EMPTY_GROUP = IncludeGroup("empty") // Default name for a joining group private const val DEFAULT_GROUP_NAME = "joinedGroup" } @@ -106,17 +104,11 @@ class EnchantConflictManager { } // Find or create the selected group for the conflict val groupList = section.getStringList(CONFLICT_GROUP_PATH) - val finalGroup: AbstractMaterialGroup - if(groupList.size < 1){ - finalGroup = DEFAULT_EMPTY_GROUP - }else if(groupList.size == 1){ - finalGroup = findGroup(groupList[0], itemManager, conflictName) - }else{ - finalGroup = IncludeGroup(DEFAULT_GROUP_NAME) - for (groupName in groupList) { - finalGroup.addToPolicy(findGroup(groupName, itemManager, conflictName)) - } + val finalGroup = IncludeGroup(DEFAULT_GROUP_NAME) + for (groupName in groupList) { + finalGroup.addToPolicy(findGroup(groupName, itemManager, conflictName)) } + // Return conflict return EnchantConflictGroup(conflictName, finalGroup, minBeforeBlock) } @@ -125,7 +117,7 @@ class EnchantConflictManager { val group = itemManager.get(groupName) if(group == null){ CustomAnvil.instance.logger.warning("Group $groupName do not exist but is ask by conflict $conflictName") - return DEFAULT_EMPTY_GROUP + return IncludeGroup("error_placeholder") } return group diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/ChatEventListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/ChatEventListener.kt new file mode 100644 index 0000000..a7ea8da --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/ChatEventListener.kt @@ -0,0 +1,47 @@ +package xyz.alexcrea.cuanvil.listener + +import io.delilaheve.CustomAnvil +import org.bukkit.Bukkit +import org.bukkit.entity.HumanEntity +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.player.AsyncPlayerChatEvent +import org.bukkit.event.player.PlayerQuitEvent +import java.util.* +import java.util.concurrent.ConcurrentHashMap +import java.util.function.Consumer + +class ChatEventListener : Listener{ + + private val playerListenMap: ConcurrentHashMap> = ConcurrentHashMap() + + fun setListenedCallback(playeruuid: UUID, callback: Consumer) { + playerListenMap[playeruuid] = callback + } + + fun setListenedCallback(player: HumanEntity, callback: Consumer) { + setListenedCallback(player.uniqueId, callback) + } + + @EventHandler + fun onQuit(event: PlayerQuitEvent) { + val eventCallback = playerListenMap.remove(event.player.uniqueId) ?: return + eventCallback.accept(null) + + } + + @EventHandler + fun onChat(event: AsyncPlayerChatEvent) { + if (event.isCancelled) return + val player = event.player + val eventCallback = playerListenMap.remove(player.uniqueId) ?: return + + event.isCancelled = true + + // sync callback with default server thread + Bukkit.getScheduler().runTask(CustomAnvil.instance, Runnable { + eventCallback.accept(event.message) + }) + } + +} \ No newline at end of file