diff --git a/src/main/java/world/arainu/core/metaverseplugin/MetaversePlugin.java b/src/main/java/world/arainu/core/metaverseplugin/MetaversePlugin.java index f2e7c57..4b31a5c 100644 --- a/src/main/java/world/arainu/core/metaverseplugin/MetaversePlugin.java +++ b/src/main/java/world/arainu/core/metaverseplugin/MetaversePlugin.java @@ -29,6 +29,7 @@ import world.arainu.core.metaverseplugin.gui.Gui; import world.arainu.core.metaverseplugin.gui.MenuItem; import world.arainu.core.metaverseplugin.iphone.Bank; +import world.arainu.core.metaverseplugin.iphone.ChestLock; import world.arainu.core.metaverseplugin.iphone.Drilling; import world.arainu.core.metaverseplugin.iphone.LinkDiscord; import world.arainu.core.metaverseplugin.iphone.MoveSurvival; @@ -39,6 +40,7 @@ import world.arainu.core.metaverseplugin.iphone.iPhoneEnderDragon; import world.arainu.core.metaverseplugin.listener.AdvancementListener; import world.arainu.core.metaverseplugin.listener.BankListener; +import world.arainu.core.metaverseplugin.listener.ChestLockListener; import world.arainu.core.metaverseplugin.listener.DrillingListener; import world.arainu.core.metaverseplugin.listener.MoneyListener; import world.arainu.core.metaverseplugin.listener.MunicipalCreateListener; @@ -55,6 +57,7 @@ import world.arainu.core.metaverseplugin.utils.sqlUtil; import java.io.File; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -179,6 +182,11 @@ private void loadGuis() { iPhoneStore.addGuiItem(new MenuItem("エンドラを復活させる", new iPhoneEnderDragon()::executeGui, true, Material.END_STONE), (p) -> !Gui.isEnderDragonLiving(p) && Gui.isPlayerInEnd(p)); iPhoneStore.addGuiItem(new MenuItem("自治体", new Municipal()::executeGui, true, Material.END_STONE), (p) -> Objects.equals(ServerStore.getServerName(), "survival")); iPhoneStore.addGuiItem(new MenuItem("discordと連携する", new LinkDiscord()::executeGui, true, Material.PAPER), (p) -> DiscordSRV.getPlugin().getAccountLinkManager().getDiscordId(p.getUniqueId()) == null); + ItemStack chestItem = new ItemStack(Material.TRIPWIRE_HOOK); + ItemMeta chestMeta = chestItem.getItemMeta(); + chestMeta.lore(Arrays.asList(Component.text("チェストに向かって使用することで"),Component.text("チェストを個人用チェストにすることができます。"),Component.text("300円/個").color(NamedTextColor.GOLD))); + chestItem.setItemMeta(chestMeta); + iPhoneStore.addGuiItem(new MenuItem("チェストの鍵を購入する", new ChestLock()::executeGui, true, chestItem), (p) -> Objects.equals(ServerStore.getServerName(), "survival")); } /** @@ -196,6 +204,7 @@ public void setListener() { PM.registerEvents(new MunicipalCreateListener(), this); PM.registerEvents(new MoneyListener(), this); PM.registerEvents(new DrillingListener(), this); + PM.registerEvents(new ChestLockListener(), this); if(Objects.equals(ServerStore.getServerName(), "survival")) { PM.registerEvents(new AdvancementListener(), this); } diff --git a/src/main/java/world/arainu/core/metaverseplugin/iphone/ChestLock.java b/src/main/java/world/arainu/core/metaverseplugin/iphone/ChestLock.java new file mode 100644 index 0000000..a566401 --- /dev/null +++ b/src/main/java/world/arainu/core/metaverseplugin/iphone/ChestLock.java @@ -0,0 +1,39 @@ +package world.arainu.core.metaverseplugin.iphone; + +import lombok.Getter; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.milkbowl.vault.economy.Economy; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataType; +import world.arainu.core.metaverseplugin.MetaversePlugin; +import world.arainu.core.metaverseplugin.gui.MenuItem; +import world.arainu.core.metaverseplugin.utils.ChatUtil; +import world.arainu.core.metaverseplugin.utils.ItemUtil; + +import java.util.Arrays; + +/** + * iPhoneからチェストの鍵を入手するクラス。 + * @author kumitatepazuru + */ +public class ChestLock extends iPhoneBase{ + @Getter + private static final NamespacedKey chestIDKey = new NamespacedKey(MetaversePlugin.getInstance(), "metaverse-key"); + + @Override + public void executeGui(MenuItem menuItem) { + ItemStack chestKey = new ItemStack(Material.TRIPWIRE_HOOK); + ItemMeta keyMeta = chestKey.getItemMeta(); + keyMeta.displayName(Component.text("設定されていない鍵").color(NamedTextColor.GOLD)); + keyMeta.lore(Arrays.asList(Component.text("チェストに向かって使用することで"),Component.text("チェストに鍵をかけられる。"))); + keyMeta.getPersistentDataContainer().set(chestIDKey,PersistentDataType.INTEGER,1); + chestKey.setItemMeta(keyMeta); + ItemUtil.addItem(chestKey, menuItem.getClicker().getInventory(), menuItem.getClicker()); + Economy econ = MetaversePlugin.getEcon(); + ChatUtil.success(menuItem.getClicker(), econ.format(300) + "を支払い鍵を与えました。"); + } +} diff --git a/src/main/java/world/arainu/core/metaverseplugin/listener/ChestLockListener.java b/src/main/java/world/arainu/core/metaverseplugin/listener/ChestLockListener.java new file mode 100644 index 0000000..740fe2e --- /dev/null +++ b/src/main/java/world/arainu/core/metaverseplugin/listener/ChestLockListener.java @@ -0,0 +1,152 @@ +package world.arainu.core.metaverseplugin.listener; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.SoundCategory; +import org.bukkit.block.Block; +import org.bukkit.block.Chest; +import org.bukkit.block.DoubleChest; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockExplodeEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import world.arainu.core.metaverseplugin.MetaversePlugin; +import world.arainu.core.metaverseplugin.iphone.ChestLock; +import world.arainu.core.metaverseplugin.utils.ChatUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.UUID; + +/** + * チェストロックシステムを実装するクラス。 + * + * @author kumitatepazuru + */ +public class ChestLockListener implements Listener { + /** + * プレイヤーがチェストを右クリックしたときの処理をする関数。 + * @param e イベント + */ + @EventHandler + public void onPlayerInteract(PlayerInteractEvent e) { + Player player = e.getPlayer(); + if (e.getAction().isRightClick() && !player.isSneaking() && e.getClickedBlock() != null) { + if (e.getClickedBlock().getType() == Material.CHEST) { + Chest state = (Chest) e.getClickedBlock().getState(); + PersistentDataContainer persistentDataContainer = state.getPersistentDataContainer(); + if (player.getInventory().getItemInMainHand().getType() != Material.AIR) { + if (player.getInventory().getItemInMainHand().getItemMeta().getPersistentDataContainer().has(ChestLock.getChestIDKey(), PersistentDataType.INTEGER)) { + e.setCancelled(true); + if (persistentDataContainer.has(ChestLock.getChestIDKey(), PersistentDataType.STRING)) { + ChatUtil.error(player, "チェストをには既に鍵がかかっています!"); + } else { + InventoryHolder holder = state.getInventory().getHolder(); + List chests; + if (holder instanceof DoubleChest doubleChest) { + chests = Arrays.asList((Chest) doubleChest.getLeftSide(), (Chest) doubleChest.getRightSide()); + } else { + chests = Collections.singletonList(state); + } + for (Chest i : chests) { + i.getPersistentDataContainer().set(ChestLock.getChestIDKey(), PersistentDataType.STRING, player.getUniqueId().toString()); + i.update(); + } + player.getInventory().setItemInMainHand(new ItemStack(Material.AIR)); + ChatUtil.success(player, "チェストに鍵をかけました。\n今後はこのチェストの破壊や閲覧はあなたしかできません。\n再設置をすると鍵は外れます。"); + } + return; + } + } + if (persistentDataContainer.has(ChestLock.getChestIDKey(), PersistentDataType.STRING)) { + UUID target = UUID.fromString(Objects.requireNonNull(persistentDataContainer.get(ChestLock.getChestIDKey(), PersistentDataType.STRING))); + if (!player.getUniqueId().equals(target) && !player.isOp()) { + player.sendActionBar(Component.text("チェストはロックされています!").color(NamedTextColor.RED)); + player.playSound(player.getLocation(), Sound.BLOCK_CHEST_LOCKED, SoundCategory.BLOCKS, 1, 1f); + e.setCancelled(true); + } else if(player.isOp()){ + ChatUtil.warning(player,"ロックされているチェストを開いています。"); + } + } + } + } + } + + /** + * ブロックが爆破によって破壊されないようにする関数。 + * + * @param e  イベント + */ + @EventHandler + public void onEntityExplode(EntityExplodeEvent e) { + breakCheck(e.blockList()); + } + + /** + * ブロックが爆破によって破壊されないようにする関数。 + * + * @param e  イベント + */ + @EventHandler + public void onBlockExplode(BlockExplodeEvent e) { + breakCheck(e.blockList()); + } + + /** + * ロック済みチェストが所有者以外のプレイヤーによって破壊されないようにする関数。 + * + * @param e  イベント + */ + @EventHandler + public void onBlockBreak(BlockBreakEvent e) { + Block block = e.getBlock(); + if (block.getType().equals(Material.CHEST) && !e.getPlayer().isOp()) { + PersistentDataContainer persistentDataContainer = ((Chest) block.getState()).getPersistentDataContainer(); + if(!persistentDataContainer.has(ChestLock.getChestIDKey(), PersistentDataType.STRING)){ + return; + } + if (!(Objects.equals(persistentDataContainer.get(ChestLock.getChestIDKey(), PersistentDataType.STRING), e.getPlayer().getUniqueId().toString()))) { + e.setCancelled(true); + } + } + } + + private void breakCheck(List blockList) { + blockList.forEach(block -> { + if (block.getType().equals(Material.CHEST)) { + PersistentDataContainer persistentDataContainer = ((Chest) block.getState()).getPersistentDataContainer(); + if (persistentDataContainer.has(ChestLock.getChestIDKey(), PersistentDataType.STRING)) { + String uuid = persistentDataContainer.get(ChestLock.getChestIDKey(), PersistentDataType.STRING); + List items = new ArrayList<>(); + for (int i = 0; i < 27; i++) { + items.add(((Chest) block.getState()).getInventory().getItem(i)); + } + ((Chest) block.getState()).getInventory().clear(); + block.setType(Material.AIR); + Bukkit.getServer().getScheduler().runTaskLater(MetaversePlugin.getInstance(), () -> { + Chest state = (Chest) block.getState(); + block.setType(Material.CHEST); + state.getPersistentDataContainer().set(ChestLock.getChestIDKey(), PersistentDataType.STRING, Objects.requireNonNull(uuid)); + state.update(); + for (int i = 0; i < 27; i++) { + state.getInventory().setItem(i, items.get(i)); + } + }, 1); + } + } + }); + } +} diff --git a/src/main/java/world/arainu/core/metaverseplugin/listener/DrillingListener.java b/src/main/java/world/arainu/core/metaverseplugin/listener/DrillingListener.java index 4381583..1e08f05 100644 --- a/src/main/java/world/arainu/core/metaverseplugin/listener/DrillingListener.java +++ b/src/main/java/world/arainu/core/metaverseplugin/listener/DrillingListener.java @@ -157,27 +157,27 @@ public void onBlockBreak(BlockBreakEvent e) { } /** - * ブロックが爆破によって破壊したときにブロックデータを削除する関数。 + * ブロックが爆破によって破壊されないようにする関数。 * @param e イベント */ @EventHandler public void onEntityExplode(EntityExplodeEvent e) { e.blockList().forEach(block -> { if(block.hasMetadata("metaverse-drilling")){ - Bukkit.getServer().getScheduler().runTaskLater(MetaversePlugin.getInstance(),() -> block.getLocation().getBlock().setType(Material.BRICKS),1); + Bukkit.getServer().getScheduler().runTaskLater(MetaversePlugin.getInstance(),() -> block.setType(Material.BRICKS),1); } }); } /** - * ブロックが爆破によって破壊したときにブロックデータを削除する関数。 + * ブロックが爆破によって破壊されないようにする関数。 * @param e イベント */ @EventHandler public void onBlockExplode(BlockExplodeEvent e) { e.blockList().forEach(block -> { if(block.hasMetadata("metaverse-drilling")){ - Bukkit.getServer().getScheduler().runTaskLater(MetaversePlugin.getInstance(),() -> block.getLocation().getBlock().setType(Material.BRICKS),1); + Bukkit.getServer().getScheduler().runTaskLater(MetaversePlugin.getInstance(),() -> block.setType(Material.BRICKS),1); } }); } @@ -342,8 +342,8 @@ private void update(Inventory inv, Block block) { // ┗━━━━━━━━━┛ ↓+Z方向 @EventHandler public void onBlockClick(PlayerInteractEvent e) { - if (e.getAction().isRightClick() && !e.getPlayer().isSneaking()) { - Block block = Objects.requireNonNull(e.getClickedBlock()); + if (e.getAction().isRightClick() && !e.getPlayer().isSneaking() && e.getClickedBlock() != null) { + Block block = e.getClickedBlock(); if (!block.getMetadata("metaverse-drilling").isEmpty()) { UUID playerUID = (UUID) block.getMetadata("metaverse-drilling").get(0).value(); if (Objects.requireNonNull(playerUID).equals(e.getPlayer().getUniqueId())) { diff --git a/src/main/java/world/arainu/core/metaverseplugin/utils/ChatUtil.java b/src/main/java/world/arainu/core/metaverseplugin/utils/ChatUtil.java index 78ab290..a3feeef 100644 --- a/src/main/java/world/arainu/core/metaverseplugin/utils/ChatUtil.java +++ b/src/main/java/world/arainu/core/metaverseplugin/utils/ChatUtil.java @@ -2,6 +2,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.TextReplacementConfig; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.ChatColor; import org.bukkit.Sound; @@ -132,7 +133,7 @@ public static void success(Player p, String message, Boolean playsound) { public static void success(Player p, TextComponent message, Boolean playsound) { MetaversePlugin.logger().info(ComponentUtil.toString( Component.text("[").append(p.displayName()).append(Component.text("] 成功>> ")).append(message))); - p.sendMessage(Component.text("[メタバースプラグイン] ").append(message).color(NamedTextColor.GREEN)); + p.sendMessage(Component.text("[メタバースプラグイン] ").append(message).replaceText(TextReplacementConfig.builder().match("\n").replacement("\n[メタバースプラグイン] ").build()).color(NamedTextColor.GREEN)); if (playsound) { p.playSound(p.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, SoundCategory.PLAYERS, 1, 1f); }