From 66dafb06e2bb5874fe055077d72711cc705d44e3 Mon Sep 17 00:00:00 2001 From: acrylic-style Date: Wed, 24 Jul 2024 10:09:10 +0900 Subject: [PATCH] add trashprotect --- build.gradle.kts | 2 +- .../com/github/mori01231/lifecore/LifeCore.kt | 16 +- .../lifecore/command/TrashProtectCommand.java | 37 ++++ .../lifecore/config/TrashProtectConfig.kt | 33 ++++ .../lifecore/gui/CommandListScreen.kt | 1 + .../lifecore/gui/TrashProtectScreen.java | 184 ++++++++++++++++++ .../lifecore/listener/TrashListener.kt | 4 +- src/main/resources/plugin.yml | 7 + 8 files changed, 276 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/github/mori01231/lifecore/command/TrashProtectCommand.java create mode 100644 src/main/java/com/github/mori01231/lifecore/config/TrashProtectConfig.kt create mode 100644 src/main/java/com/github/mori01231/lifecore/gui/TrashProtectScreen.java diff --git a/build.gradle.kts b/build.gradle.kts index a9a8401..3367d10 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,7 @@ plugins { } group = "net.azisaba" -version = "6.14.1" +version = "6.15.0" java { toolchain.languageVersion.set(JavaLanguageVersion.of(8)) diff --git a/src/main/java/com/github/mori01231/lifecore/LifeCore.kt b/src/main/java/com/github/mori01231/lifecore/LifeCore.kt index a94e528..7d9bb96 100644 --- a/src/main/java/com/github/mori01231/lifecore/LifeCore.kt +++ b/src/main/java/com/github/mori01231/lifecore/LifeCore.kt @@ -5,9 +5,9 @@ import com.github.mori01231.lifecore.command.* import com.github.mori01231.lifecore.config.* import com.github.mori01231.lifecore.gui.CommandListScreen import com.github.mori01231.lifecore.gui.DropProtectScreen +import com.github.mori01231.lifecore.gui.TrashProtectScreen import com.github.mori01231.lifecore.listener.* import com.github.mori01231.lifecore.listener.item.* -import com.github.mori01231.lifecore.map.SerializedMapDataRenderer import com.github.mori01231.lifecore.network.PacketHandler import com.github.mori01231.lifecore.region.PlayerRegionManager import com.github.mori01231.lifecore.util.* @@ -17,11 +17,7 @@ import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import org.bukkit.Bukkit import org.bukkit.command.CommandExecutor -import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer -import org.bukkit.craftbukkit.v1_15_R1.map.CraftMapRenderer -import org.bukkit.craftbukkit.v1_15_R1.map.CraftMapView import org.bukkit.entity.ItemFrame -import org.bukkit.inventory.meta.MapMeta import org.bukkit.plugin.java.JavaPlugin import java.io.IOException import java.net.InetSocketAddress @@ -43,6 +39,8 @@ class LifeCore : JavaPlugin() { private var httpServer: HttpServer? = null lateinit var dropProtectConfig: DropProtectConfig private set + lateinit var trashProtectConfig: TrashProtectConfig + private set val customBlockManager = CustomBlockManager(this) var customModelDataWrench = 0 var customModelDataBlank = 0 @@ -76,6 +74,12 @@ class LifeCore : JavaPlugin() { } dropProtectConfig = yaml.decodeFromString(it.readText()) } + dataFolder.resolve("trash-protect.yml").let { + if (!it.exists()) { + it.writeText(yaml.encodeToString(TrashProtectConfig())) + } + trashProtectConfig = yaml.decodeFromString(it.readText()) + } // save every 5 minutes Bukkit.getScheduler().runTaskTimerAsynchronously(this, 20 * 60 * 5, 20 * 60 * 5) { @@ -134,6 +138,7 @@ class LifeCore : JavaPlugin() { registerCommand("ngword", NgWordCommand(this)) registerCommand("dropnotify", DropNotifyCommand()) registerCommand("dropprotect", DropProtectCommand(this)) + registerCommand("trashprotect", TrashProtectCommand(this)) registerCommand("damagelog", DamageLogCommand()) registerCommand("servermoney", ServerMoneyCommand(this)) registerCommand("fixtime", FixTimeCommand) @@ -278,6 +283,7 @@ class LifeCore : JavaPlugin() { pm.registerEvents(DeathLoopListener(), this) pm.registerEvents(DropNotifyListener(), this) pm.registerEvents(DropProtectScreen.EventListener(this), this) + pm.registerEvents(TrashProtectScreen.EventListener(this), this) pm.registerEvents(UnableCraftListener(), this) pm.registerEvents(AZISAVIORListener(this), this) pm.registerEvents(DamageLogListener(), this) diff --git a/src/main/java/com/github/mori01231/lifecore/command/TrashProtectCommand.java b/src/main/java/com/github/mori01231/lifecore/command/TrashProtectCommand.java new file mode 100644 index 0000000..b287087 --- /dev/null +++ b/src/main/java/com/github/mori01231/lifecore/command/TrashProtectCommand.java @@ -0,0 +1,37 @@ +package com.github.mori01231.lifecore.command; + +import com.github.mori01231.lifecore.LifeCore; +import com.github.mori01231.lifecore.gui.TrashProtectScreen; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; + +public class TrashProtectCommand implements TabExecutor { + private final LifeCore plugin; + + public TrashProtectCommand(@NotNull LifeCore plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage("This command can only be executed by players."); + return true; + } + Player player = (Player) sender; + player.openInventory(new TrashProtectScreen(plugin, player).getInventory()); + return true; + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { + return Collections.emptyList(); + } +} diff --git a/src/main/java/com/github/mori01231/lifecore/config/TrashProtectConfig.kt b/src/main/java/com/github/mori01231/lifecore/config/TrashProtectConfig.kt new file mode 100644 index 0000000..79d6fd1 --- /dev/null +++ b/src/main/java/com/github/mori01231/lifecore/config/TrashProtectConfig.kt @@ -0,0 +1,33 @@ +package com.github.mori01231.lifecore.config + +import kotlinx.serialization.Serializable +import java.util.UUID + +@Serializable +data class TrashProtectConfig( + val players: MutableMap> = mutableMapOf(), +) { + /** + * Returns the mutable set of rarities that the player has enabled drop protection for. + */ + operator fun get(uuid: UUID): MutableSet = + players.computeIfAbsent(uuid.toString()) { mutableSetOf() } + + /** + * Returns true if the player has enabled drop protection for the given rarity. + */ + fun contains(uuid: UUID, item: String): Boolean { + return this[uuid].contains(item) + } + + /** + * Toggles the drop protection for the given rarity for the given player. + */ + fun toggle(uuid: UUID, item: String) { + if (contains(uuid, item)) { + this[uuid].remove(item) + } else { + this[uuid].add(item) + } + } +} diff --git a/src/main/java/com/github/mori01231/lifecore/gui/CommandListScreen.kt b/src/main/java/com/github/mori01231/lifecore/gui/CommandListScreen.kt index 06833c7..d0e9a45 100644 --- a/src/main/java/com/github/mori01231/lifecore/gui/CommandListScreen.kt +++ b/src/main/java/com/github/mori01231/lifecore/gui/CommandListScreen.kt @@ -42,6 +42,7 @@ class CommandListScreen(val player: Player) : InventoryHolder { } }, CommandInfo(CommandType.Toggle, "ドロップ保護", listOf("レア度別でアイテムをドロップできるようにするかを", "切り替えられます。"), "/dropprotect"), + CommandInfo(CommandType.Toggle, "ゴミ保護", listOf("レア度別でアイテムをゴミ箱できるようにするかを", "切り替えられます。"), "/trashprotect"), CommandInfo(CommandType.Toggle, "ドロップ通知", listOf("アイテムをドロップしたときに通知を表示します。"), "/dropnotify") { if (DropNotifyFile.contains(it.uniqueId)) { CommandInfo.State.Enabled diff --git a/src/main/java/com/github/mori01231/lifecore/gui/TrashProtectScreen.java b/src/main/java/com/github/mori01231/lifecore/gui/TrashProtectScreen.java new file mode 100644 index 0000000..b67f972 --- /dev/null +++ b/src/main/java/com/github/mori01231/lifecore/gui/TrashProtectScreen.java @@ -0,0 +1,184 @@ +package com.github.mori01231.lifecore.gui; + +import com.github.mori01231.lifecore.LifeCore; +import com.github.mori01231.lifecore.util.ItemUtil; +import net.azisaba.rarity.api.RarityAPIProvider; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; + +public class TrashProtectScreen implements InventoryHolder { + private final Inventory inventory = Bukkit.createInventory(this, 9, "TrashProtect"); + private final LifeCore plugin; + private final Player player; + + public TrashProtectScreen(@NotNull LifeCore plugin, @NotNull Player player) { + this.plugin = plugin; + this.player = player; + reset(); + } + + public void reset() { + String noRarityLore = plugin.getTrashProtectConfig().contains(player.getUniqueId(), "no_rarity") ? ChatColor.GREEN + "有効" : ChatColor.RED + "無効"; + String commonName = RarityAPIProvider.get().getRarityById("common").getDisplayName(player); + String commonLore = plugin.getTrashProtectConfig().contains(player.getUniqueId(), "common") ? ChatColor.GREEN + "有効" : ChatColor.RED + "無効"; + String uncommonName = RarityAPIProvider.get().getRarityById("uncommon").getDisplayName(player); + String uncommonLore = plugin.getTrashProtectConfig().contains(player.getUniqueId(), "uncommon") ? ChatColor.GREEN + "有効" : ChatColor.RED + "無効"; + String rareName = RarityAPIProvider.get().getRarityById("rare").getDisplayName(player); + String rareLore = plugin.getTrashProtectConfig().contains(player.getUniqueId(), "rare") ? ChatColor.GREEN + "有効" : ChatColor.RED + "無効"; + String epicName = RarityAPIProvider.get().getRarityById("epic").getDisplayName(player); + String epicLore = plugin.getTrashProtectConfig().contains(player.getUniqueId(), "epic") ? ChatColor.GREEN + "有効" : ChatColor.RED + "無効"; + String legendaryName = RarityAPIProvider.get().getRarityById("legendary").getDisplayName(player); + String legendaryLore = plugin.getTrashProtectConfig().contains(player.getUniqueId(), "legendary") ? ChatColor.GREEN + "有効" : ChatColor.RED + "無効"; + String mythicName = RarityAPIProvider.get().getRarityById("mythic").getDisplayName(player); + String mythicLore = plugin.getTrashProtectConfig().contains(player.getUniqueId(), "mythic") ? ChatColor.GREEN + "有効" : ChatColor.RED + "無効"; + String specialName = RarityAPIProvider.get().getRarityById("special").getDisplayName(player); + String specialLore = plugin.getTrashProtectConfig().contains(player.getUniqueId(), "special") ? ChatColor.GREEN + "有効" : ChatColor.RED + "無効"; + inventory.setItem(0, ItemUtil.createItemStack(Material.PAPER, 1, item -> { + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.WHITE + "レア度が付与されていないアイテム"); + meta.setLore(Collections.singletonList(noRarityLore)); + item.setItemMeta(meta); + } + })); + inventory.setItem(1, ItemUtil.createItemStack(Material.COBBLESTONE, 1, item -> { + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', commonName)); + meta.setLore(Collections.singletonList(commonLore)); + item.setItemMeta(meta); + } + })); + inventory.setItem(2, ItemUtil.createItemStack(Material.IRON_BLOCK, 1, item -> { + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', uncommonName)); + meta.setLore(Collections.singletonList(uncommonLore)); + item.setItemMeta(meta); + } + })); + inventory.setItem(3, ItemUtil.createItemStack(Material.GOLD_BLOCK, 1, item -> { + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', rareName)); + meta.setLore(Collections.singletonList(rareLore)); + item.setItemMeta(meta); + } + })); + inventory.setItem(4, ItemUtil.createItemStack(Material.EMERALD_BLOCK, 1, item -> { + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', epicName)); + meta.setLore(Collections.singletonList(epicLore)); + item.setItemMeta(meta); + } + })); + inventory.setItem(5, ItemUtil.createItemStack(Material.DIAMOND_BLOCK, 1, item -> { + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', legendaryName)); + meta.setLore(Collections.singletonList(legendaryLore)); + item.setItemMeta(meta); + } + })); + inventory.setItem(6, ItemUtil.createItemStack(Material.ENCHANTED_GOLDEN_APPLE, 1, item -> { + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', mythicName)); + meta.setLore(Collections.singletonList(mythicLore)); + item.setItemMeta(meta); + } + })); + inventory.setItem(7, ItemUtil.createItemStack(Material.NETHER_STAR, 1, item -> { + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', specialName)); + meta.setLore(Collections.singletonList(specialLore)); + item.setItemMeta(meta); + } + })); + inventory.setItem(8, ItemUtil.createItemStack(Material.BARRIER, 1, item -> { + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(ChatColor.RED + "閉じる"); + item.setItemMeta(meta); + } + })); + } + + @NotNull + @Override + public Inventory getInventory() { + return inventory; + } + + public static class EventListener implements Listener { + private final LifeCore plugin; + + public EventListener(@NotNull LifeCore plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onClick(InventoryClickEvent e) { + if (!(e.getInventory().getHolder() instanceof TrashProtectScreen)) { + return; + } + e.setCancelled(true); + if (e.getClickedInventory() == null || !(e.getClickedInventory().getHolder() instanceof TrashProtectScreen)) { + return; + } + TrashProtectScreen screen = (TrashProtectScreen) e.getInventory().getHolder(); + switch (e.getSlot()) { + case 0: { + plugin.getTrashProtectConfig().toggle(screen.player.getUniqueId(), "no_rarity"); + break; + } + case 1: { + plugin.getTrashProtectConfig().toggle(screen.player.getUniqueId(), "common"); + break; + } + case 2: { + plugin.getTrashProtectConfig().toggle(screen.player.getUniqueId(), "uncommon"); + break; + } + case 3: { + plugin.getTrashProtectConfig().toggle(screen.player.getUniqueId(), "rare"); + break; + } + case 4: { + plugin.getTrashProtectConfig().toggle(screen.player.getUniqueId(), "epic"); + break; + } + case 5: { + plugin.getTrashProtectConfig().toggle(screen.player.getUniqueId(), "legendary"); + break; + } + case 6: { + plugin.getTrashProtectConfig().toggle(screen.player.getUniqueId(), "mythic"); + break; + } + case 7: { + plugin.getTrashProtectConfig().toggle(screen.player.getUniqueId(), "special"); + break; + } + case 8: { + screen.player.closeInventory(); + return; + } + } + screen.reset(); + } + } +} diff --git a/src/main/java/com/github/mori01231/lifecore/listener/TrashListener.kt b/src/main/java/com/github/mori01231/lifecore/listener/TrashListener.kt index 6f6c164..a40e811 100644 --- a/src/main/java/com/github/mori01231/lifecore/listener/TrashListener.kt +++ b/src/main/java/com/github/mori01231/lifecore/listener/TrashListener.kt @@ -30,13 +30,13 @@ class TrashListener(private val plugin: LifeCore) : Listener { val item = e.inventory.getItem(i) ?: continue val rarity: Rarity? = rarityAPI.getRarityByItemStack(item) val shouldCancel = if (rarity == null) { - if (plugin.dropProtectConfig.contains(e.whoClicked.uniqueId, "no_rarity")) { + if (plugin.trashProtectConfig.contains(e.whoClicked.uniqueId, "no_rarity")) { true } else { continue } } else { - plugin.dropProtectConfig.contains(e.whoClicked.uniqueId, rarity.id) + plugin.trashProtectConfig.contains(e.whoClicked.uniqueId, rarity.id) } if (shouldCancel) { e.inventory.setItem(i, null) diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 952dfe5..9b24aa2 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -133,6 +133,11 @@ commands: description: "protect items from being dropped" permission: lifecore.dropprotect usage: "/dropprotect" + trashprotect: + description: "protect items from being gomi'd" + permission: lifecore.trashprotect + usage: "/trashprotect" + aliases: ['gomiprotect'] damagelog: description: "view damage log" permission: lifecore.damagelog @@ -293,6 +298,8 @@ permissions: default: true lifecore.dropprotect: default: true + lifecore.trashprotect: + default: true lifecore.damagelog: default: true lifecore.respawn: