Skip to content

Commit

Permalink
fix: sharedInventoryのコマンドが正しく動作しないのを修正
Browse files Browse the repository at this point in the history
  • Loading branch information
rito528 committed Oct 4, 2023
1 parent 1b1fed5 commit 9511344
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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]

Expand Down
Original file line number Diff line number Diff line change
@@ -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 =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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")
})
}
}

0 comments on commit 9511344

Please sign in to comment.