From 95113448821d4692ed0ac6ad578c564e9befddc5 Mon Sep 17 00:00:00 2001 From: rito528 <39003544+rito528@users.noreply.github.com> Date: Wed, 4 Oct 2023 22:11:18 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20sharedInventory=E3=81=AE=E3=82=B3?= =?UTF-8?q?=E3=83=9E=E3=83=B3=E3=83=89=E3=81=8C=E6=AD=A3=E3=81=97=E3=81=8F?= =?UTF-8?q?=E5=8B=95=E4=BD=9C=E3=81=97=E3=81=AA=E3=81=84=E3=81=AE=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unchama/seichiassist/SeichiAssist.scala | 2 +- .../subsystems/sharedinventory/System.scala | 4 +- .../command/ShareInventoryCommand.scala | 122 +++++++++--------- .../targetedeffect/player/CommandEffect.scala | 9 ++ 4 files changed, 73 insertions(+), 64 deletions(-) diff --git a/src/main/scala/com/github/unchama/seichiassist/SeichiAssist.scala b/src/main/scala/com/github/unchama/seichiassist/SeichiAssist.scala index d6e424b975..167c87cd81 100644 --- a/src/main/scala/com/github/unchama/seichiassist/SeichiAssist.scala +++ b/src/main/scala/com/github/unchama/seichiassist/SeichiAssist.scala @@ -403,7 +403,7 @@ class SeichiAssist extends JavaPlugin() { mineStackSystem.api private lazy val sharedInventorySystem: subsystems.sharedinventory.System[IO] = { - import PluginExecutionContexts.timer + import PluginExecutionContexts.{timer, onMainThread} subsystems.sharedinventory.System.wired[IO, IO].unsafeRunSync() } diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/System.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/System.scala index f9758db42b..9c8ca2dbab 100644 --- a/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/System.scala +++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/System.scala @@ -1,6 +1,7 @@ package com.github.unchama.seichiassist.subsystems.sharedinventory import cats.effect.{Concurrent, ConcurrentEffect, Timer} +import com.github.unchama.minecraft.actions.OnMinecraftServerThread import com.github.unchama.seichiassist.meta.subsystem.Subsystem import com.github.unchama.seichiassist.subsystems.sharedinventory.bukkit.command.ShareInventoryCommand import com.github.unchama.seichiassist.subsystems.sharedinventory.domain.bukkit.InventoryContents @@ -23,7 +24,8 @@ object System { import cats.implicits._ - def wired[F[_]: ConcurrentEffect: Timer, G[_]: Concurrent]: G[System[F]] = { + def wired[F[_]: ConcurrentEffect: Timer: OnMinecraftServerThread, G[_]: Concurrent] + : G[System[F]] = { implicit val persistence: SharedInventoryPersistence[F] = new JdbcSharedInventoryPersistence[F] diff --git a/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/bukkit/command/ShareInventoryCommand.scala b/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/bukkit/command/ShareInventoryCommand.scala index 93347afcdd..7cf7009c98 100644 --- a/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/bukkit/command/ShareInventoryCommand.scala +++ b/src/main/scala/com/github/unchama/seichiassist/subsystems/sharedinventory/bukkit/command/ShareInventoryCommand.scala @@ -1,106 +1,104 @@ package com.github.unchama.seichiassist.subsystems.sharedinventory.bukkit.command -import cats.effect.ConcurrentEffect.ops.toAllConcurrentEffectOps -import cats.effect.{ConcurrentEffect, IO, Sync} +import cats.data.Kleisli +import cats.effect.{ConcurrentEffect, Sync} +import com.github.unchama.minecraft.actions.OnMinecraftServerThread import com.github.unchama.seichiassist.commands.contextual.builder.BuilderTemplates.playerCommandBuilder -import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts.onMainThread import com.github.unchama.seichiassist.subsystems.sharedinventory.SharedInventoryAPI import com.github.unchama.seichiassist.subsystems.sharedinventory.domain.SharedFlag import com.github.unchama.seichiassist.subsystems.sharedinventory.domain.bukkit.InventoryContents import com.github.unchama.seichiassist.util.InventoryOperations -import com.github.unchama.targetedeffect.commandsender.MessageEffect -import com.github.unchama.targetedeffect.player.CommandEffect -import com.github.unchama.targetedeffect.{SequentialEffect, TargetedEffect} +import com.github.unchama.targetedeffect.commandsender.MessageEffectF +import com.github.unchama.targetedeffect.player.CommandEffectF +import com.github.unchama.targetedeffect.{SequentialEffect, TargetedEffectF} import org.bukkit.ChatColor._ import org.bukkit.command.TabExecutor import org.bukkit.entity.Player import org.bukkit.inventory.ItemStack import org.bukkit.{Bukkit, Material} -class ShareInventoryCommand[F[_]: ConcurrentEffect]( +class ShareInventoryCommand[F[_]: ConcurrentEffect: OnMinecraftServerThread]( implicit sharedInventoryAPI: SharedInventoryAPI[F, Player] ) { import cats.implicits._ val executor: TabExecutor = playerCommandBuilder - .buildWithExecutionF { context => + .buildWithExecutionCSEffect { context => val sender = context.sender - for { - // TODO: this `toIO` is not needed - sharedFlag <- sharedInventoryAPI.sharedFlag(sender).toIO - eff <- - if (sharedFlag == SharedFlag.Sharing) { - withdrawFromSharedInventory(sender) - } else { - depositToSharedInventory(sender) - } - } yield eff + + Kleisli.liftF(sharedInventoryAPI.sharedFlag(sender)).flatMap { sharedFlag => + if (sharedFlag == SharedFlag.Sharing) { + withdrawFromSharedInventory(sender) + } else { + depositToSharedInventory(sender) + } + } } .asNonBlockingTabExecutor() - private def withdrawFromSharedInventory(player: Player): IO[TargetedEffect[Player]] = { + private def withdrawFromSharedInventory(player: Player): TargetedEffectF[F, Player] = { val uuid = player.getUniqueId - val eff = for { - oldSharedFlag <- sharedInventoryAPI.sharedFlag(player) - loadedInventory <- sharedInventoryAPI.load(uuid) - _ <- sharedInventoryAPI.clear(uuid) - newSharedFlag <- sharedInventoryAPI.sharedFlag(player) - _ <- Sync[F] - .delay { - val playerInventory = player.getInventory - val inventoryContents = loadedInventory.get.inventoryContents - // 手持ちのアイテムをドロップする - playerInventory - .getContents - .filterNot(itemStack => itemStack == null || itemStack.getType == Material.AIR) - .foreach(itemStack => dropIfNotEmpty(Some(itemStack), player)) - // 取り出したアイテムをセットする - playerInventory.setContents(inventoryContents.toArray) - Bukkit.getLogger.info(s"${player.getName}がアイテム取り出しを実施(DB)書き換え成功") - } - .whenA(oldSharedFlag != newSharedFlag && loadedInventory.nonEmpty) + (for { + oldSharedFlag <- Kleisli.liftF(sharedInventoryAPI.sharedFlag(player)) + loadedInventory <- Kleisli.liftF(sharedInventoryAPI.load(uuid)) + _ <- Kleisli.liftF(sharedInventoryAPI.clear(uuid)) + newSharedFlag <- Kleisli.liftF(sharedInventoryAPI.sharedFlag(player)) + _ <- Kleisli.liftF( + Sync[F] + .delay { + val playerInventory = player.getInventory + val inventoryContents = loadedInventory.get.inventoryContents + // 手持ちのアイテムをドロップする + playerInventory + .getContents + .filterNot(itemStack => itemStack == null || itemStack.getType == Material.AIR) + .foreach(itemStack => dropIfNotEmpty(Some(itemStack), player)) + // 取り出したアイテムをセットする + playerInventory.setContents(inventoryContents.toArray) + Bukkit.getLogger.info(s"${player.getName}がアイテム取り出しを実施(DB)書き換え成功") + } + .whenA(oldSharedFlag != newSharedFlag && loadedInventory.nonEmpty) + ) } yield { if (oldSharedFlag != newSharedFlag && loadedInventory.nonEmpty) - MessageEffect(s"${GREEN}アイテムを取得しました。手持ちにあったアイテムはドロップしました。") + MessageEffectF(s"${GREEN}アイテムを取得しました。手持ちにあったアイテムはドロップしました。") else if (oldSharedFlag == newSharedFlag) - MessageEffect(s"$RESET$RED${BOLD}もう少し待ってからアイテム取り出しを行ってください。") + MessageEffectF(s"$RESET$RED${BOLD}もう少し待ってからアイテム取り出しを行ってください。") else - MessageEffect(s"$RESET$RED${BOLD}収納アイテムが存在しません。") - } - - eff.toIO + MessageEffectF(s"$RESET$RED${BOLD}収納アイテムが存在しません。") + }).flatten } - private def depositToSharedInventory(player: Player): IO[TargetedEffect[Player]] = { + private def depositToSharedInventory(player: Player): TargetedEffectF[F, Player] = { val uuid = player.getUniqueId val playerInventory = player.getInventory val inventoryContents = playerInventory.getContents.toList if (inventoryContents.forall(_ == null)) - return IO.pure(MessageEffect(s"$RESET$RED${BOLD}収納アイテムが存在しません。")) + return MessageEffectF(s"$RESET$RED${BOLD}収納アイテムが存在しません。") - val eff = for { - oldSharedFlag <- sharedInventoryAPI.sharedFlag(player) - _ <- sharedInventoryAPI.save(uuid, InventoryContents(inventoryContents)) - newSharedFlag <- sharedInventoryAPI.sharedFlag(player) - _ <- Sync[F] - .delay { - playerInventory.clear() - Bukkit.getLogger.info(s"${player.getName}がアイテム収納を実施(SQL送信成功)") - } - .whenA(oldSharedFlag != newSharedFlag) + (for { + oldSharedFlag <- Kleisli.liftF(sharedInventoryAPI.sharedFlag(player)) + _ <- Kleisli.liftF(sharedInventoryAPI.save(uuid, InventoryContents(inventoryContents))) + newSharedFlag <- Kleisli.liftF(sharedInventoryAPI.sharedFlag(player)) + _ <- Kleisli.liftF( + Sync[F] + .delay { + playerInventory.clear() + Bukkit.getLogger.info(s"${player.getName}がアイテム収納を実施(SQL送信成功)") + } + .whenA(oldSharedFlag != newSharedFlag) + ) } yield { if (oldSharedFlag == newSharedFlag) - MessageEffect(s"$RESET$RED${BOLD}もう少し待ってからアイテムを収納してください。") + MessageEffectF(s"$RESET$RED${BOLD}もう少し待ってからアイテムを収納してください。") else SequentialEffect( - CommandEffect("stick"), - MessageEffect(s"${GREEN}アイテムを収納しました。10秒以上あとに、手持ちを空にして取り出してください。") + CommandEffectF("stick"), + MessageEffectF(s"${GREEN}アイテムを収納しました。10秒以上あとに、手持ちを空にして取り出してください。") ) - } - - eff.toIO + }).flatten } private def dropIfNotEmpty(itemStackOption: Option[ItemStack], to: Player): Unit = diff --git a/src/main/scala/com/github/unchama/targetedeffect/player/CommandEffect.scala b/src/main/scala/com/github/unchama/targetedeffect/player/CommandEffect.scala index 1da9b76645..fe4e75fd1d 100644 --- a/src/main/scala/com/github/unchama/targetedeffect/player/CommandEffect.scala +++ b/src/main/scala/com/github/unchama/targetedeffect/player/CommandEffect.scala @@ -18,3 +18,12 @@ object CommandEffect { }) } } + +object CommandEffectF { + def apply[F[_]: OnMinecraftServerThread](string: String): Kleisli[F, Player, Unit] = + Kleisli { player => + OnMinecraftServerThread[F].runAction(SyncIO { + player.chat(s"/$string") + }) + } +}