currently refactoring a lot

This commit is contained in:
kento2 2026-07-04 12:25:54 +02:00
parent 7fe7409a15
commit a32805a623
46 changed files with 571 additions and 642 deletions

115
.idea/workspace.xml generated
View file

@ -4,59 +4,52 @@
<option name="autoReloadType" value="SELECTIVE" /> <option name="autoReloadType" value="SELECTIVE" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="56c685a1-f609-4ffd-a951-849beb2a7f8d" name="Changes" comment="."> <list default="true" id="56c685a1-f609-4ffd-a951-849beb2a7f8d" name="Changes" comment="currently refactoring a lot">
<change afterPath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/PlayerManager.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/scheduler/Task.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/playermanager/PlayerManagerImpl.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/scheduler/TaskImpl.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/convention/ScrowMessageStyle.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/scheduler/Tasks.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/messaging/MessageBroker.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/command/CoinsCommand.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/messaging/RequestHandler.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/command/CoinsGetLiteral.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/messaging/ResultRepository.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/command/CoinsSetLiteral.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/InstanceManager.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/../build-logic/convention/src/main/kotlin/de/kentoj/scrow/DatabaseConvention.kt" beforeDir="false" afterPath="$PROJECT_DIR$/../build-logic/convention/src/main/kotlin/de/kentoj/scrow/DatabaseConvention.kt" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/InstanceManagerImpl.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/utils/EnvUtils.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../build-logic/convention/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/../build-logic/convention/build.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../build-logic/convention/src/main/kotlin/de/kentoj/scrow/BaseDependenciesConvention.kt" beforeDir="false" afterPath="$PROJECT_DIR$/../build-logic/convention/src/main/kotlin/de/kentoj/scrow/BaseDependenciesConvention.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../build-logic/convention/src/main/kotlin/de/kentoj/scrow/ScrowRepositoryConvention.kt" beforeDir="false" afterPath="$PROJECT_DIR$/../build-logic/convention/src/main/kotlin/de/kentoj/scrow/ScrowRepositoryConvention.kt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../build-logic/settings.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/../build-logic/settings.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-api/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-api/build.gradle.kts" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-api/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-api/build.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/EconomyService.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/misc/EconomyService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/PlayerManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/misc/PlayerManager.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ScrowAPI.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ScrowAPI.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ScrowAPI.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/ScrowAPI.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/friends/FriendRequestService.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/friends/FriendRequestService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/friends/FriendshipService.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-api/src/main/java/de/kentoj/scrow/bukkit/friends/FriendshipService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/build.gradle.kts" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/build.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/CoreImplPlugin.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/ScrowAPISurface.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownCommand.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDeployServerLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDeployServerLiteral.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDeployServerLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDeployServerLiteral.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDestroyServerLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDestroyServerLiteral.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDestroyServerLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownDestroyServerLiteral.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownListServersLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownListServersLiteral.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownListServersLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/crown/CrownListServersLiteral.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/CoinsCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/CoinsCommand.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/CoinsCommand.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/InMemoryEconomyService.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/InMemoryEconomyService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/MongoEconomyService.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/PostgresEconomyService.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/economy/PostgresEconomyService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendAddLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendAddLiteral.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendAddLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendAddLiteral.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendCommand.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendCommand.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendListLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendListLiteral.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendListLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendListLiteral.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendRemoveLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendRemoveLiteral.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendRemoveLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendRemoveLiteral.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendRequestsLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendRequestsLiteral.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendRequestsLiteral.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/command/FriendRequestsLiteral.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/friendship/InMemoryFriendshipService.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/friendship/InMemoryFriendshipService.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/friendship/InMemoryFriendshipService.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/friendship/InMemoryFriendshipService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/handler/FriendAddHandler.java" beforeDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/friendship/MongoFriendshipService.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/friendship/PostgresFriendshipService.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/friendship/PostgresFriendshipService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/request/InMemoryFriendRequestService.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/request/InMemoryFriendRequestService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/request/MongoFriendRequestService.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/request/PostgresFriendRequestService.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/friends/request/PostgresFriendRequestService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/playermanager/PlayerManagerImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/playermanager/PlayerManagerImpl.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/server/LobbyCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/server/LobbyCommand.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/server/LobbyCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/server/LobbyCommand.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/server/PlayCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/server/PlayCommand.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/server/PlayCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/server/PlayCommand.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-lib/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/core-lib/build.gradle.kts" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-lib/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/core-lib/build.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/messaging/NatsRepository.java" beforeDir="false" /> <change beforePath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/InstanceManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/InstanceManager.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/messaging/SubscriptionContext.java" beforeDir="false" /> <change beforePath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/InstanceManagerImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/InstanceManagerImpl.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/messaging/respose/SafeErrorResult.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/messaging/respose/SafeResult.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/messaging/respose/SafeSuccessResult.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/ServerInstance.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/ServerInstance.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/ServerManager.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/core-lib/src/main/java/de/kentoj/scrowlib/servermanager/ServerManagerImpl.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/core-velocity-api/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-api/build.gradle.kts" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-velocity-api/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-api/build.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-velocity-api/src/main/java/de/kentoj/scrow/velocity/ScrowAPI.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-api/src/main/java/de/kentoj/scrow/velocity/ScrowAPI.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-velocity-impl/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-impl/build.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/CoreVelocityPlugin.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/CoreVelocityPlugin.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/ScrowAPISurface.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/ScrowAPISurface.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/command/OnlineCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/command/OnlineCommand.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/command/OnlineCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/command/OnlineCommand.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/privmsg/MsgCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/privmsg/MsgCommand.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/privmsg/MsgCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/privmsg/MsgCommand.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/privmsg/ReplyCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/privmsg/ReplyCommand.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/privmsg/ReplyCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/privmsg/ReplyCommand.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/server/SendPlayerWatchdog.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/server/SendPlayerWatchdog.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/server/ServerRegisterWatchdog.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/server/ServerRegisterWatchdog.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/server/ServerRegisterWatchdog.java" beforeDir="false" afterPath="$PROJECT_DIR$/core-velocity-impl/src/main/java/de/kentoj/scrow/corevelocity/server/ServerRegisterWatchdog.java" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
@ -152,13 +145,7 @@
<component name="Git.Settings"> <component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" /> <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component> </component>
<component name="GradleScriptDefinitionsStorage" workingDir="$PROJECT_DIR$" gradleHome="$USER_HOME$/.gradle/wrapper/dists/gradle-8.11-bin/c4te04g51qsyw1bxcb929u7br/gradle-8.11" javaHome="/usr/lib/jvm/openjdk21" gradleVersion="8.11"> <component name="GradleScriptDefinitionsStorage" workingDir="$PROJECT_DIR$" gradleHome="$USER_HOME$/.gradle/wrapper/dists/gradle-8.11-bin/c4te04g51qsyw1bxcb929u7br/gradle-8.11" javaHome="/usr/lib/jvm/openjdk21" gradleVersion="8.11" />
<option name="jvmArguments">
<list>
<option value="-Didea.gradle.download.sources.force=true" />
</list>
</option>
</component>
<component name="HighlightingSettingsPerFile"> <component name="HighlightingSettingsPerFile">
<setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.projectreactor/reactor-core/3.8.5/ed6c3f423d84bf282e50a4f7432a8d65af321efb/reactor-core-3.8.5-sources.jar!/reactor/core/publisher/Mono.java" root0="SKIP_INSPECTION" /> <setting file="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.projectreactor/reactor-core/3.8.5/ed6c3f423d84bf282e50a4f7432a8d65af321efb/reactor-core-3.8.5-sources.jar!/reactor/core/publisher/Mono.java" root0="SKIP_INSPECTION" />
</component> </component>
@ -174,33 +161,34 @@
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent"><![CDATA[{ <component name="PropertiesComponent">{
"keyToString": { &quot;keyToString&quot;: {
"Gradle.Download Sources.executor": "Run", &quot;Gradle.Download Sources.executor&quot;: &quot;Run&quot;,
"Gradle.core [build].executor": "Run", &quot;Gradle.core [build].executor&quot;: &quot;Debug&quot;,
"Gradle.core [clean].executor": "Run", &quot;Gradle.core [clean].executor&quot;: &quot;Run&quot;,
"Gradle.core [publishAllPublicationsToScrowRepository].executor": "Run", &quot;Gradle.core [publishAllPublicationsToScrowRepository].executor&quot;: &quot;Run&quot;,
"Gradle.core [publishCoreLibPublicationToScrowRepository].executor": "Run", &quot;Gradle.core [publishCoreLibPublicationToScrowRepository].executor&quot;: &quot;Run&quot;,
"Gradle.core:core-bukkit-api [build].executor": "Run", &quot;Gradle.core:core-bukkit-api [build].executor&quot;: &quot;Run&quot;,
"Gradle.core:core-bukkit-api [clean].executor": "Run", &quot;Gradle.core:core-bukkit-api [clean].executor&quot;: &quot;Run&quot;,
"Gradle.core:core-lib [publishAllPublicationsToScrowRepository].executor": "Run", &quot;Gradle.core:core-lib [publishAllPublicationsToScrowRepository].executor&quot;: &quot;Run&quot;,
"Gradle.core:core-lib [publishCoreLibPublicationToMavenLocal].executor": "Run", &quot;Gradle.core:core-lib [publishCoreLibPublicationToMavenLocal].executor&quot;: &quot;Run&quot;,
"Gradle.core:core-lib [publishCoreLibPublicationToScrowRepository].executor": "Run", &quot;Gradle.core:core-lib [publishCoreLibPublicationToScrowRepository].executor&quot;: &quot;Run&quot;,
"ModuleVcsDetector.initialDetectionPerformed": "true", &quot;ModuleVcsDetector.initialDetectionPerformed&quot;: &quot;true&quot;,
"RunOnceActivity.ShowReadmeOnStart": "true", &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true", &quot;RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252&quot;: &quot;true&quot;,
"RunOnceActivity.git.unshallow": "true", &quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
"git-widget-placeholder": "master", &quot;git-widget-placeholder&quot;: &quot;master&quot;,
"kotlin-language-version-configured": "true", &quot;kotlin-language-version-configured&quot;: &quot;true&quot;,
"last_opened_file_path": "/home/a/src/scrow", &quot;last_opened_file_path&quot;: &quot;/home/a/src/scrow&quot;,
"project.structure.last.edited": "Project", &quot;project.structure.last.edited&quot;: &quot;Project&quot;,
"project.structure.proportion": "0.15", &quot;project.structure.proportion&quot;: &quot;0.15&quot;,
"project.structure.side.proportion": "0.6268199", &quot;project.structure.side.proportion&quot;: &quot;0.6268199&quot;,
"settings.editor.selected.configurable": "preferences.pluginManager" &quot;settings.editor.selected.configurable&quot;: &quot;preferences.pluginManager&quot;
} }
}]]></component> }</component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CreateClassDialog.RecentsKey"> <key name="CreateClassDialog.RecentsKey">
<recent name="de.kentoj.scrow.bukkit.economy.command" />
<recent name="de.kentoj.scrowlib.messaging" /> <recent name="de.kentoj.scrowlib.messaging" />
</key> </key>
<key name="MoveFile.RECENT_KEYS"> <key name="MoveFile.RECENT_KEYS">
@ -388,6 +376,7 @@
<component name="VcsManagerConfiguration"> <component name="VcsManagerConfiguration">
<MESSAGE value="." /> <MESSAGE value="." />
<MESSAGE value="fix: unable to leave regions when unloaded" /> <MESSAGE value="fix: unable to leave regions when unloaded" />
<option name="LAST_COMMIT_MESSAGE" value="fix: unable to leave regions when unloaded" /> <MESSAGE value="currently refactoring a lot" />
<option name="LAST_COMMIT_MESSAGE" value="currently refactoring a lot" />
</component> </component>
</project> </project>

View file

@ -4,7 +4,7 @@ plugins {
id("de.kentoj.scrow.scrow-repository") id("de.kentoj.scrow.scrow-repository")
id("de.kentoj.scrow.base-dependencies") id("de.kentoj.scrow.base-dependencies")
id("de.kentoj.scrow.java-library") id("de.kentoj.scrow.java-library")
id("de.kentoj.scrow.reactor") id("de.kentoj.scrow.database")
} }
group = "de.kentoj.scrow" group = "de.kentoj.scrow"
@ -24,9 +24,9 @@ dependencies {
api("io.nats:jnats:2.25.2") api("io.nats:jnats:2.25.2")
// http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-core // http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-core
api("de.kentoj.scrow:kencommandapi-core:0.21") api("de.kentoj.scrow:kencommandapi-core:0.22")
// http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-bukkit // http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-bukkit
api("de.kentoj.scrow:kencommandapi-bukkit:0.21") api("de.kentoj.scrow:kencommandapi-bukkit:0.22")
} }
publishing { publishing {

View file

@ -1,10 +0,0 @@
package de.kentoj.scrow.bukkit;
import com.leakyabstractions.result.api.Result;
import java.util.UUID;
public interface PlayerManager {
Result<Void, String> sendPlayer(UUID uuid, String instanceHandle);
}

View file

@ -3,24 +3,29 @@ package de.kentoj.scrow.bukkit;
import de.kentoj.kencommandapi.CommandAPI; import de.kentoj.kencommandapi.CommandAPI;
import de.kentoj.scrow.bukkit.friends.FriendRequestService; import de.kentoj.scrow.bukkit.friends.FriendRequestService;
import de.kentoj.scrow.bukkit.friends.FriendshipService; import de.kentoj.scrow.bukkit.friends.FriendshipService;
import de.kentoj.scrow.bukkit.misc.EconomyService;
import de.kentoj.scrow.bukkit.misc.PlayerManager;
import de.kentoj.scrow.bukkit.region.RegionManager; import de.kentoj.scrow.bukkit.region.RegionManager;
import de.kentoj.scrowlib.connection.DatabaseConnectionFactory;
import de.kentoj.scrowlib.servermanager.InstanceManager; import de.kentoj.scrowlib.servermanager.InstanceManager;
import io.nats.client.Connection; import io.nats.client.Connection;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.bukkit.plugin.Plugin;
import org.jdbi.v3.core.Jdbi;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import reactor.core.scheduler.Scheduler;
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ScrowAPI { public class ScrowAPI {
/**
* Might be null in testing environments
*/
@Getter @Getter
private static DatabaseConnectionFactory dbConFactory; private static @Nullable Jdbi jdbi;
@Getter @ApiStatus.Internal
private static Scheduler minecraftScheduler; public static Plugin plugin;
@Getter @Getter
private static EconomyService economyService; private static EconomyService economyService;
@Getter @Getter
@ -44,8 +49,8 @@ public class ScrowAPI {
} }
@ApiStatus.Internal @ApiStatus.Internal
public static void setMinecraftScheduler(Scheduler minecraftScheduler) { public static void setCorePlugin(Plugin plugin) {
ScrowAPI.minecraftScheduler = minecraftScheduler; ScrowAPI.plugin = plugin;
} }
@ApiStatus.Internal @ApiStatus.Internal
@ -69,8 +74,8 @@ public class ScrowAPI {
} }
@ApiStatus.Internal @ApiStatus.Internal
public static void setDbConFactory(@Nullable DatabaseConnectionFactory dbConFactory) { public static void setJdbi(@Nullable Jdbi jdbi) {
ScrowAPI.dbConFactory = dbConFactory; ScrowAPI.jdbi = jdbi;
} }
@ApiStatus.Internal @ApiStatus.Internal

View file

@ -1,26 +1,23 @@
package de.kentoj.scrow.bukkit.friends; package de.kentoj.scrow.bukkit.friends;
import org.jetbrains.annotations.NotNull; import java.util.List;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.UUID; import java.util.UUID;
public interface FriendRequestService { public interface FriendRequestService {
Flux<@NotNull FriendRequest> getFriendRequestsTo(UUID playerId); List<FriendRequest> getFriendRequestsTo(UUID playerId);
Flux<@NotNull FriendRequest> getFriendRequestsFrom(UUID playerId); List<FriendRequest> getFriendRequestsFrom(UUID playerId);
Mono<@NotNull FriendRequest> getFriendRequest(UUID from, UUID to); FriendRequest getFriendRequest(UUID from, UUID to);
/** /**
* @return True if request saved, false if already existing request found. * @return True if request saved, false if already existing request found.
*/ */
Mono<@NotNull Boolean> saveFriendRequest(FriendRequest friendRequest); boolean saveFriendRequest(FriendRequest friendRequest);
/** /**
* @return True if request deleted, false if none found. * @return True if request deleted, false if none found.
*/ */
Mono<@NotNull Boolean> deleteFriendRequest(UUID from, UUID to); boolean deleteFriendRequest(UUID from, UUID to);
} }

View file

@ -1,24 +1,21 @@
package de.kentoj.scrow.bukkit.friends; package de.kentoj.scrow.bukkit.friends;
import org.jetbrains.annotations.NotNull; import java.util.List;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.UUID; import java.util.UUID;
public interface FriendshipService { public interface FriendshipService {
Mono<@NotNull Friendship> getFriendship(UUID uuid1, UUID uuid2); Friendship getFriendship(UUID uuid1, UUID uuid2);
Flux<@NotNull Friendship> getFriendships(UUID playerId); List<Friendship> getFriendships(UUID playerId);
/* /*
* @return True if friendship saved, false if friendship already exists * @return True if friendship saved, false if friendship already exists
*/ */
Mono<@NotNull Boolean> saveFriendship(Friendship playerIds); boolean saveFriendship(Friendship playerIds);
/** /**
* @return True if friendship deleted, false if none found * @return True if friendship deleted, false if none found
*/ */
Mono<@NotNull Boolean> deleteFriendship(UUID uuid1, UUID uuid2); boolean deleteFriendship(UUID uuid1, UUID uuid2);
} }

View file

@ -1,7 +1,4 @@
package de.kentoj.scrow.bukkit; package de.kentoj.scrow.bukkit.misc;
import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Mono;
import java.util.UUID; import java.util.UUID;
@ -10,24 +7,24 @@ public interface EconomyService {
/** /**
* @throws IllegalArgumentException if amount is less than 0 * @throws IllegalArgumentException if amount is less than 0
*/ */
Mono<@NotNull Integer> getCoins(UUID playerId); int getCoins(UUID playerId);
/** /**
* @param playerId uuid of player * @param playerId uuid of player
* @throws IllegalArgumentException if amount is less than 0 * @throws IllegalArgumentException if amount is less than 0
*/ */
Mono<@NotNull Void> depositCoins(UUID playerId, int amount); void depositCoins(UUID playerId, int amount);
/** /**
* @param playerId uuid of player * @param playerId uuid of player
* @return true on success, false on insufficient funds * @return true on success, false on insufficient funds
* @throws IllegalArgumentException if amount is less than 0 * @throws IllegalArgumentException if amount is less than 0
*/ */
Mono<@NotNull Boolean> tryWithdrawCoins(UUID playerId, int amount); boolean tryWithdrawCoins(UUID playerId, int amount);
/** /**
* @param playerId uuid of player * @param playerId uuid of player
* @throws IllegalArgumentException if amount is less than 0 * @throws IllegalArgumentException if amount is less than 0
*/ */
Mono<@NotNull Void> setCoins(UUID playerId, int amount); void setCoins(UUID playerId, int amount);
} }

View file

@ -0,0 +1,8 @@
package de.kentoj.scrow.bukkit.misc;
import java.util.UUID;
public interface PlayerManager {
void sendPlayer(UUID uuid, String instanceHandle);
}

View file

@ -0,0 +1,51 @@
package de.kentoj.scrow.bukkit.scheduler;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public interface Task<T> {
CompletableFuture<T> asFuture();
default Task<?> runSync(Runnable task) {
return mapSync(__ -> {
task.run();
return null;
});
}
default <S> Task<S> supplySync(Supplier<S> supplier) {
return mapSync(__ -> supplier.get());
}
default Task<?> thenSync(Consumer<T> consumer) {
return mapSync(previous -> {
consumer.accept(previous);
return null;
});
}
<S> Task<S> mapSync(Function<T, S> mapper);
default Task<?> runAsync(Runnable task) {
return mapAsync(__ -> {
task.run();
return null;
});
}
default <S> Task<S> supplyAsync(Supplier<S> supplier) {
return mapAsync(__ -> supplier.get());
}
default Task<?> thenAsync(Consumer<T> consumer) {
return mapAsync(previous -> {
consumer.accept(previous);
return null;
});
}
<S> Task<S> mapAsync(Function<T, S> mapper);
}

View file

@ -0,0 +1,56 @@
package de.kentoj.scrow.bukkit.scheduler;
import de.kentoj.scrow.bukkit.ScrowAPI;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import org.bukkit.Bukkit;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* A Task runs entirely async, when sync is used, a subtask is run on the main thread and the async thread
* blocks until the subtask returns.
*
* @param <T> type of computed result
*/
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
public class TaskImpl<T> implements Task<T> {
private static final ExecutorService EXECUTOR = Executors.newVirtualThreadPerTaskExecutor();
private final Supplier<T> compute;
@Override
public CompletableFuture<T> asFuture() {
return CompletableFuture.supplyAsync(compute, EXECUTOR);
}
/**
* Maps the last result on the main thread
*/
public <S> Task<S> mapSync(Function<T, S> mapper) {
Supplier<S> supplier = () -> {
try {
return Bukkit.getScheduler().callSyncMethod(ScrowAPI.plugin, () -> mapper.apply(compute.get())).get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
};
return new TaskImpl<>(supplier);
}
/**
* Maps the last result async
*/
public <S> Task<S> mapAsync(Function<T, S> mapper) {
return new TaskImpl<>(() -> mapper.apply(compute.get()));
}
}

View file

@ -0,0 +1,43 @@
package de.kentoj.scrow.bukkit.scheduler;
import de.kentoj.scrow.bukkit.ScrowAPI;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.bukkit.Bukkit;
import java.util.concurrent.ExecutionException;
import java.util.function.Supplier;
@NoArgsConstructor(access = AccessLevel.NONE)
public class Tasks {
public static <T> Task<T> supplyAsync(Supplier<T> supplier) {
return new TaskImpl<>(supplier);
}
public static Task<?> runAsync(Runnable task) {
return supplyAsync(() -> {
task.run();
return null;
});
}
public static <T> Task<T> supplySync(Supplier<T> supplier) {
return new TaskImpl<>(() -> {
try {
return Bukkit.getScheduler().callSyncMethod(ScrowAPI.plugin, supplier::get).get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
});
}
public static Task<?> runSync(Runnable task) {
return supplySync(() -> {
task.run();
return null;
});
}
}

View file

@ -22,12 +22,7 @@ dependencies {
implementation(project(":core-bukkit-api")) implementation(project(":core-bukkit-api"))
// http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-core // http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-core
implementation("de.kentoj.scrow:kencommandapi-core:0.21") implementation("de.kentoj.scrow:kencommandapi-core:0.22")
// TODO remove, we use postgres now
// https://www.mongodb.com/docs/languages/java/reactive-streams-driver/current/get-started/download-and-install/
implementation(platform("org.mongodb:mongodb-driver-bom:5.6.1"))
implementation("org.mongodb:mongodb-driver-reactivestreams")
} }
tasks { tasks {

View file

@ -1,13 +1,13 @@
package de.kentoj.scrow.bukkit; package de.kentoj.scrow.bukkit;
import de.kentoj.scrow.bukkit.crown.CrownCommand; import de.kentoj.scrow.bukkit.crown.CrownCommand;
import de.kentoj.scrow.bukkit.economy.CoinsCommand; import de.kentoj.scrow.bukkit.economy.command.CoinsCommand;
import de.kentoj.scrow.bukkit.economy.command.CoinsSetLiteral;
import de.kentoj.scrow.bukkit.friends.command.FriendCommand; import de.kentoj.scrow.bukkit.friends.command.FriendCommand;
import de.kentoj.scrow.bukkit.region.RegionPlayerTracker; import de.kentoj.scrow.bukkit.region.RegionPlayerTracker;
import de.kentoj.scrow.bukkit.region.RegionTask; import de.kentoj.scrow.bukkit.region.RegionTask;
import de.kentoj.scrow.bukkit.server.LobbyCommand; import de.kentoj.scrow.bukkit.server.LobbyCommand;
import de.kentoj.scrow.bukkit.server.PlayCommand; import de.kentoj.scrow.bukkit.server.PlayCommand;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.io.IOException; import java.io.IOException;
@ -26,8 +26,8 @@ public class CoreImplPlugin extends JavaPlugin {
ScrowAPISurface.initScrowAPI(this, ENABLE_DATABASE); ScrowAPISurface.initScrowAPI(this, ENABLE_DATABASE);
{ {
ScrowAPI.getCommandApi().register(new FriendCommand().getRootNode());
ScrowAPI.getCommandApi().register(new CoinsCommand().getRootNode()); ScrowAPI.getCommandApi().register(new CoinsCommand().getRootNode());
ScrowAPI.getCommandApi().register(new FriendCommand().getRootNode());
ScrowAPI.getCommandApi().register(new CrownCommand().getRootNode()); ScrowAPI.getCommandApi().register(new CrownCommand().getRootNode());
ScrowAPI.getCommandApi().register(new PlayCommand().getRootNode()); ScrowAPI.getCommandApi().register(new PlayCommand().getRootNode());
ScrowAPI.getCommandApi().register(new LobbyCommand().getRootNode()); ScrowAPI.getCommandApi().register(new LobbyCommand().getRootNode());

View file

@ -27,9 +27,7 @@ import java.io.IOException;
public class ScrowAPISurface { public class ScrowAPISurface {
public static void initScrowAPI(Plugin plugin, boolean enableDatabase) { public static void initScrowAPI(Plugin plugin, boolean enableDatabase) {
ScrowAPI.setMinecraftScheduler(Schedulers.fromExecutor(cmd -> { ScrowAPI.setCorePlugin(plugin);
Bukkit.getScheduler().runTask(plugin, cmd);
}));
try { try {
String natsHost = EnvUtils.envOrThrow("HOST_NATS"); String natsHost = EnvUtils.envOrThrow("HOST_NATS");
@ -44,23 +42,23 @@ public class ScrowAPISurface {
if (enableDatabase) { if (enableDatabase) {
ConnectionFactory factory = ConnectionFactories.get(EnvUtils.envOrThrow("HOST_POSTGRES")); ConnectionFactory factory = ConnectionFactories.get(EnvUtils.envOrThrow("HOST_POSTGRES"));
ScrowAPI.setDbConFactory(new DatabaseConnectionFactoryImpl(factory)); ScrowAPI.setJdbi(new DatabaseConnectionFactoryImpl(factory));
} }
ScrowAPI.setRegionManager(new RegionManagerImpl()); ScrowAPI.setRegionManager(new RegionManagerImpl());
ScrowAPI.setCommandApi(new CommandAPI(plugin)); ScrowAPI.setCommandApi(new CommandAPI(plugin));
ScrowAPI.setInstanceManager(new InstanceManagerImpl(ScrowAPI.getNats())); ScrowAPI.setInstanceManager(new InstanceManagerImpl(ScrowAPI.getNats()));
ScrowAPI.setEconomyService(ScrowAPI.getDbConFactory() != null ? ScrowAPI.setEconomyService(ScrowAPI.getJdbi() != null ?
new PostgresEconomyService(ScrowAPI.getDbConFactory()) : new InMemoryEconomyService()); new PostgresEconomyService(ScrowAPI.getJdbi()) : new InMemoryEconomyService());
ScrowAPI.setFriendRequestService(ScrowAPI.getDbConFactory() != null ? ScrowAPI.setFriendRequestService(ScrowAPI.getJdbi() != null ?
new PostgresFriendRequestService(ScrowAPI.getDbConFactory()) : new InMemoryFriendRequestService()); new PostgresFriendRequestService(ScrowAPI.getJdbi()) : new InMemoryFriendRequestService());
ScrowAPI.setFriendshipService(ScrowAPI.getDbConFactory() != null ? ScrowAPI.setFriendshipService(ScrowAPI.getJdbi() != null ?
new PostgresFriendshipService(ScrowAPI.getDbConFactory()) : new InMemoryFriendshipService()); new PostgresFriendshipService(ScrowAPI.getJdbi()) : new InMemoryFriendshipService());
} }
public static void destroyScrowAPI() { public static void destroyScrowAPI() {
try { try {
ScrowAPI.getDbConFactory().close(); ScrowAPI.getJdbi().close();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View file

@ -28,7 +28,7 @@ public class CrownDeployServerLiteral implements CommandExecutor<CommandSender>
} }
@Override @Override
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) { public CompletableFuture<Result<Object,String>> execute(CommandContext<CommandSender> ctx) {
var template = ctx.getArg(templateArg); var template = ctx.getArg(templateArg);
return ScrowAPI.getInstanceManager().deployInstance(template) return ScrowAPI.getInstanceManager().deployInstance(template)
.map(server -> { .map(server -> {

View file

@ -38,7 +38,7 @@ public class CrownDestroyServerLiteral implements CommandExecutor<CommandSender>
} }
@Override @Override
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) { public CompletableFuture<Result<Object,String>> execute(CommandContext<CommandSender> ctx) {
var handle = ctx.getArg(handleArg); var handle = ctx.getArg(handleArg);
return ScrowAPI.getInstanceManager().destroyInstance(handle) return ScrowAPI.getInstanceManager().destroyInstance(handle)
.map(__ -> { .map(__ -> {

View file

@ -25,7 +25,7 @@ public class CrownListServersLiteral implements CommandExecutor<CommandSender> {
} }
@Override @Override
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) { public CompletableFuture<Result<Object,String>> execute(CommandContext<CommandSender> ctx) {
return ScrowAPI.getInstanceManager().getInstances() return ScrowAPI.getInstanceManager().getInstances()
.collectList() .collectList()
.map(list -> style.list(Component.text("Running instances:"), .map(list -> style.list(Component.text("Running instances:"),

View file

@ -1,78 +0,0 @@
package de.kentoj.scrow.bukkit.economy;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.core.Results;
import de.kentoj.kencommandapi.api.node.CommandNode;
import de.kentoj.kencommandapi.api.argument.CommandArgument;
import de.kentoj.kencommandapi.api.argument.types.IntegerArgumentType;
import de.kentoj.kencommandapi.api.invocation.CommandContext;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.api.Results;
import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType;
import de.kentoj.scrow.bukkit.ScrowAPI;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import reactor.core.scheduler.Schedulers;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
public class CoinsCommand {
@Getter
private final CommandNode<CommandSender> rootNode;
private final CommandArgument<CommandSender, OfflinePlayer> playerArg;
private final CommandArgument<CommandSender, Integer> amountArg;
public CoinsCommand() {
this.rootNode = CommandNode.node("coins", "eco");
this.playerArg = CommandArgument.arg("player", OfflinePlayerArgumentType.getInstance());
this.amountArg = CommandArgument.arg("amount", new IntegerArgumentType<>());
{
CommandNode<CommandSender> setLiteral = CommandNode.node("set");
rootNode.addLiteral(setLiteral);
setLiteral.addArgument(playerArg);
setLiteral.addArgument(amountArg);
setLiteral.setExecutor(this::setCoins);
}
{
CommandNode<CommandSender> getLiteral = CommandNode.node("get");
rootNode.addLiteral(getLiteral);
getLiteral.addArgument(playerArg);
getLiteral.setExecutor(this::getCoins);
}
}
private CompletableFuture<Result<Void,String>> getCoins(CommandContext<CommandSender> ctx) {
var player = ctx.getArg(playerArg);
return ScrowAPI.getEconomyService()
.getCoins(player.getUniqueId())
.subscribeOn(Schedulers.boundedElastic())
.publishOn(ScrowAPI.getMinecraftScheduler())
.map(amount -> {
if (player == ctx.getSender()) {
ctx.getSender().sendMessage("You have " + amount + "$");
} else {
ctx.getSender().sendMessage(player.getName() + " has " + amount + "$");
}
return Result.success();
}).toFuture();
}
private CompletableFuture<Result<Void,String>> setCoins(CommandContext<CommandSender> ctx) {
var player = ctx.getArg(playerArg);
var amount = ctx.getArg(amountArg);
return ScrowAPI.getEconomyService()
.setCoins(player.getUniqueId(), amount)
.subscribeOn(Schedulers.boundedElastic())
.publishOn(ScrowAPI.getMinecraftScheduler())
.map(__ -> {
ctx.getSender().sendMessage(player.getName() + " now has " + amount + "$");
return Results.success(null);
}).toFuture();
}
}

View file

@ -1,9 +1,7 @@
package de.kentoj.scrow.bukkit.economy; package de.kentoj.scrow.bukkit.economy;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import de.kentoj.scrow.bukkit.EconomyService; import de.kentoj.scrow.bukkit.misc.EconomyService;
import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Mono;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -14,34 +12,29 @@ public class InMemoryEconomyService implements EconomyService {
private final Map<UUID, Integer> coins = new HashMap<>(); private final Map<UUID, Integer> coins = new HashMap<>();
@Override @Override
public Mono<@NotNull Integer> getCoins(UUID playerId) { public int getCoins(UUID playerId) {
return Mono.fromSupplier(() -> coins.getOrDefault(playerId, 0)); return coins.getOrDefault(playerId, 0);
} }
@Override @Override
public Mono<@NotNull Void> setCoins(UUID playerId, int amount) { public void setCoins(UUID playerId, int amount) {
Preconditions.checkArgument(amount >= 0, "amount can not be negative"); Preconditions.checkArgument(amount >= 0, "amount can not be negative");
return Mono.fromSupplier(() -> coins.put(playerId, amount)).then(); coins.put(playerId, amount);
} }
@Override @Override
public Mono<@NotNull Void> depositCoins(UUID playerId, int amount) { public void depositCoins(UUID playerId, int amount) {
Preconditions.checkArgument(amount >= 0, "amount can not be negative"); Preconditions.checkArgument(amount >= 0, "amount can not be negative");
return Mono.fromRunnable(() -> { var cur = coins.getOrDefault(playerId, 0);
var cur = coins.getOrDefault(playerId, amount); coins.put(playerId, cur + amount);
coins.put(playerId, cur + amount);
});
} }
@Override @Override
public Mono<@NotNull Boolean> tryWithdrawCoins(UUID playerId, int amount) { public boolean tryWithdrawCoins(UUID playerId, int amount) {
Preconditions.checkArgument(amount >= 0, "amount can not be negative"); Preconditions.checkArgument(amount >= 0, "amount can not be negative");
return Mono.fromSupplier(() -> { var cur = coins.getOrDefault(playerId, 0);
var cur = coins.getOrDefault(playerId, 0); if (cur < amount) return false;
if (cur < amount) return false; coins.put(playerId, cur - amount);
return true;
coins.put(playerId, cur - amount);
return true;
});
} }
} }

View file

@ -1,74 +0,0 @@
package de.kentoj.scrow.bukkit.economy;
import com.google.common.base.Preconditions;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.UpdateOptions;
import com.mongodb.client.model.Updates;
import com.mongodb.reactivestreams.client.MongoCollection;
import com.mongodb.reactivestreams.client.MongoDatabase;
import de.kentoj.scrow.bukkit.EconomyService;
import org.bson.Document;
import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Mono;
import java.util.UUID;
// TODO log
public class MongoEconomyService implements EconomyService {
private static final String COLLECTION_NAME = "economy";
private final @NotNull MongoDatabase database;
public MongoEconomyService(MongoDatabase database) {
this.database = database;
Mono.from(database.createCollection(COLLECTION_NAME)).block();
}
@Override
public Mono<@NotNull Integer> getCoins(UUID playerId) {
return Mono.from(
getCollection().find(Filters.eq("_id", playerId)).first()
).map(result -> result.getInteger("coins")).defaultIfEmpty(0);
}
@Override
public Mono<@NotNull Void> setCoins(UUID playerId, int amount) {
Preconditions.checkArgument(amount >= 0, "amount can not be negative");
return Mono.from(
getCollection().updateOne(
Filters.eq("_id", playerId),
Updates.set("coins", amount),
new UpdateOptions().upsert(true)
)
).then();
}
@Override
public Mono<@NotNull Void> depositCoins(UUID playerId, int amount) {
Preconditions.checkArgument(amount >= 0, "amount can not be negative");
return Mono.from(getCollection().updateOne(
Filters.eq("_id", playerId),
Updates.inc("coins", amount),
new UpdateOptions().upsert(true)
)).then();
}
@Override
public Mono<@NotNull Boolean> tryWithdrawCoins(UUID playerId, int amount) {
Preconditions.checkArgument(amount >= 0, "amount can not be negative");
return Mono.from(getCollection().updateOne(
Filters.and(
Filters.eq("_id", playerId),
Filters.gte("coins", amount)
),
Updates.inc("coins", -1 * amount)
)).map(result -> result.getModifiedCount() > 0);
}
private MongoCollection<Document> getCollection() {
return database.getCollection(COLLECTION_NAME);
}
}

View file

@ -1,46 +1,46 @@
package de.kentoj.scrow.bukkit.economy; package de.kentoj.scrow.bukkit.economy;
import com.google.common.base.Preconditions; import de.kentoj.scrow.bukkit.ScrowAPI;
import de.kentoj.scrow.bukkit.EconomyService; import de.kentoj.scrow.bukkit.misc.EconomyService;
import de.kentoj.scrowlib.connection.DatabaseConnectionFactory; import org.jdbi.v3.core.Jdbi;
import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Mono;
import java.util.UUID; import java.util.UUID;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
// TODO log operations to separate table // TODO log operations to separate table
public class PostgresEconomyService implements EconomyService { public class PostgresEconomyService implements EconomyService {
private final DatabaseConnectionFactory conFactory; private final Jdbi jdbi;
public PostgresEconomyService(DatabaseConnectionFactory conFactory) { public PostgresEconomyService() {
this.conFactory = conFactory; checkNotNull(ScrowAPI.getJdbi());
conFactory.create().sql(""" this.jdbi = ScrowAPI.getJdbi();
jdbi.withHandle(h -> h.execute("""
CREATE TABLE IF NOT EXISTS economy ( CREATE TABLE IF NOT EXISTS economy (
playerId UUID NOT NULL, playerId UUID NOT NULL,
balance INTEGER NOT NULL DEFAULT 0, balance INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY(playerId) PRIMARY KEY(playerId)
) )
""").then().block(); """));
} }
@Override @Override
public Mono<@NotNull Integer> getCoins(UUID playerId) { public int getCoins(UUID playerId) {
return conFactory.create() return jdbi.withHandle(h -> h
.sql(""" .createQuery("SELECT balance FROM economy WHERE playerId = :playerId")
SELECT balance
FROM economy
WHERE playerId = :playerId
""")
.bind("playerId", playerId) .bind("playerId", playerId)
.map(row -> row.get("balance", Integer.class)) .map(row -> row.getColumn("balance", Integer.class))
.one(); .findOne()
.orElse(0));
} }
@Override @Override
public Mono<@NotNull Void> setCoins(UUID playerId, int amount) { public void setCoins(UUID playerId, int amount) {
Preconditions.checkArgument(amount >= 0, "amount can not be negative"); checkArgument(amount >= 0, "amount cannot be negative");
return conFactory.create().sql(""" jdbi.withHandle(h -> h
.createUpdate("""
INSERT INTO economy (playerId, balance) INSERT INTO economy (playerId, balance)
VALUES (:playerId, :amount) VALUES (:playerId, :amount)
ON CONFLICT (playerId) ON CONFLICT (playerId)
@ -50,13 +50,14 @@ public class PostgresEconomyService implements EconomyService {
""") """)
.bind("playerId", playerId) .bind("playerId", playerId)
.bind("amount", amount) .bind("amount", amount)
.then(); .execute());
} }
@Override @Override
public Mono<@NotNull Void> depositCoins(UUID playerId, int amount) { public void depositCoins(UUID playerId, int amount) {
Preconditions.checkArgument(amount >= 0, "amount can not be negative"); checkArgument(amount >= 0, "amount cannot be negative");
return conFactory.create().sql(""" jdbi.withHandle(h -> h.
createUpdate("""
INSERT INTO economy (playerId, balance) INSERT INTO economy (playerId, balance)
VALUES (:playerId, :amount) VALUES (:playerId, :amount)
ON CONFLICT (playerId) ON CONFLICT (playerId)
@ -66,21 +67,20 @@ public class PostgresEconomyService implements EconomyService {
""") """)
.bind("playerId", playerId) .bind("playerId", playerId)
.bind("amount", amount) .bind("amount", amount)
.then(); .execute());
} }
@Override @Override
public Mono<@NotNull Boolean> tryWithdrawCoins(UUID playerId, int amount) { public boolean tryWithdrawCoins(UUID playerId, int amount) {
Preconditions.checkArgument(amount >= 0, "amount can not be negative"); checkArgument(amount >= 0, "amount cannot be negative");
return conFactory.create().sql(""" return jdbi.withHandle(h -> h
.createUpdate("""
UPDATE economy UPDATE economy
SET balance = balance - :amount SET balance = balance - :amount
WHERE playerId = :playerId WHERE playerId = :playerId
""") """)
.bind("playerId", playerId) .bind("playerId", playerId)
.bind("amount", amount) .bind("amount", amount)
.fetch() .execute() > 0);
.rowsUpdated()
.map(updated -> updated > 0);
} }
} }

View file

@ -0,0 +1,56 @@
package de.kentoj.scrow.bukkit.economy.command;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.core.Results;
import de.kentoj.kencommandapi.api.invocation.CommandContext;
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
import de.kentoj.kencommandapi.api.node.CommandNode;
import de.kentoj.kencommandapi.api.node.RootCommandNode;
import de.kentoj.kencommandapi.api.platform.MessageStyle;
import de.kentoj.scrow.bukkit.ScrowAPI;
import de.kentoj.scrow.bukkit.ScrowAPISurface;
import de.kentoj.scrow.bukkit.scheduler.Tasks;
import de.kentoj.scrowlib.convention.ScrowMessageStyle;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@NoArgsConstructor(access = AccessLevel.NONE)
public class CoinsCommand implements CommandExecutor<CommandSender> {
@Getter
private final RootCommandNode<CommandSender> rootNode;
private final MessageStyle style;
public CoinsCommand() {
style = new ScrowMessageStyle("Coins", NamedTextColor.GOLD);
rootNode = CommandNode.rootNode(style, "coins", "bal", "balance");
rootNode.setPermission("command.coins.get.self");
var setLiteral = new CoinsSetLiteral(style).getLiteral();
setLiteral.setPermission("command.coins.set");
rootNode.addLiteral(setLiteral);
var getLiteral = new CoinsGetLiteral(style).getLiteral();
getLiteral.setPermission("command.coins.get.others");
rootNode.addLiteral(getLiteral);
}
@Override
public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
var player = ((Player) ctx.getSender());
return Tasks.supplyAsync(() ->
ScrowAPI.getEconomyService().getCoins(player.getUniqueId()))
.<Result<Object, String>>mapSync(amount -> {
player.sendMessage(style.ok("You have " + amount + "$"));
return Results.success(Optional.empty());
}).asFuture();
}
}

View file

@ -0,0 +1,50 @@
package de.kentoj.scrow.bukkit.economy.command;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.core.Results;
import de.kentoj.kencommandapi.api.argument.CommandArgument;
import de.kentoj.kencommandapi.api.invocation.CommandContext;
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
import de.kentoj.kencommandapi.api.node.CommandNode;
import de.kentoj.kencommandapi.api.platform.MessageStyle;
import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType;
import de.kentoj.scrow.bukkit.ScrowAPI;
import de.kentoj.scrow.bukkit.scheduler.Tasks;
import lombok.Getter;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
public class CoinsGetLiteral implements CommandExecutor<CommandSender> {
@Getter
private final CommandNode<CommandSender> literal;
private final MessageStyle style;
private final CommandArgument<CommandSender, OfflinePlayer> playerArg;
public CoinsGetLiteral(MessageStyle style) {
this.style = style;
playerArg = CommandArgument.arg("player", OfflinePlayerArgumentType.getInstance());
playerArg.setDefaultValueProvider(sender -> (OfflinePlayer) sender);
literal = CommandNode.node("set");
literal.addArgument(playerArg);
literal.setExecutor(this);
}
@Override
public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
var player = ctx.getArg(playerArg);
return Tasks.supplyAsync(() ->
ScrowAPI.getEconomyService().getCoins(player.getUniqueId()))
.<Result<Object, String>>mapSync(amount -> {
ctx.getSender().sendMessage(style.ok(player.getName() + " has " + amount + "$"));
return Results.success(Optional.empty());
}).asFuture();
}
}

View file

@ -0,0 +1,53 @@
package de.kentoj.scrow.bukkit.economy.command;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.core.Results;
import de.kentoj.kencommandapi.api.argument.CommandArgument;
import de.kentoj.kencommandapi.api.argument.types.IntegerArgumentType;
import de.kentoj.kencommandapi.api.invocation.CommandContext;
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
import de.kentoj.kencommandapi.api.node.CommandNode;
import de.kentoj.kencommandapi.api.platform.MessageStyle;
import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType;
import de.kentoj.scrow.bukkit.ScrowAPI;
import de.kentoj.scrow.bukkit.scheduler.Tasks;
import lombok.Getter;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
public class CoinsSetLiteral implements CommandExecutor<CommandSender> {
@Getter
private final CommandNode<CommandSender> literal;
private final MessageStyle style;
private final CommandArgument<CommandSender, OfflinePlayer> playerArg;
private final CommandArgument<CommandSender, Integer> amountArg;
public CoinsSetLiteral(MessageStyle style) {
this.style = style;
playerArg = CommandArgument.arg("player", OfflinePlayerArgumentType.getInstance());
amountArg = CommandArgument.arg("amount", new IntegerArgumentType<>());
literal = CommandNode.node("set");
literal.addArgument(playerArg);
literal.addArgument(amountArg);
literal.setExecutor(this);
}
@Override
public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
var player = ctx.getArg(playerArg);
var amount = ctx.getArg(amountArg);
return Tasks.runAsync(() ->
ScrowAPI.getEconomyService().setCoins(player.getUniqueId(), amount))
.<Result<Object, String>>supplySync(() -> {
ctx.getSender().sendMessage(style.ok(player.getName() + " now has " + amount + "$"));
return Results.success(Optional.empty());
}).asFuture();
}
}

View file

@ -36,7 +36,7 @@ public class FriendAddLiteral implements CommandExecutor<CommandSender> {
} }
@Override @Override
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) { public CompletableFuture<Result<Object,String>> execute(CommandContext<CommandSender> ctx) {
var self = (Player) ctx.getSender(); var self = (Player) ctx.getSender();
var other = ctx.getArg(playerArg); var other = ctx.getArg(playerArg);
return findAction(self, other) return findAction(self, other)

View file

@ -3,20 +3,16 @@ package de.kentoj.scrow.bukkit.friends.command;
import de.kentoj.kencommandapi.api.node.CommandNode; import de.kentoj.kencommandapi.api.node.CommandNode;
import de.kentoj.kencommandapi.api.node.RootCommandNode; import de.kentoj.kencommandapi.api.node.RootCommandNode;
import de.kentoj.scrowlib.convention.ScrowMessageStyle; import de.kentoj.scrowlib.convention.ScrowMessageStyle;
import lombok.Getter; import lombok.AccessLevel;
import net.kyori.adventure.text.Component; import lombok.NoArgsConstructor;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@NoArgsConstructor(access = AccessLevel.NONE)
public class FriendCommand { public class FriendCommand {
public static RootCommandNode<CommandSender> create() {
@Getter var style = new ScrowMessageStyle("Friends", NamedTextColor.GREEN);
private final RootCommandNode<CommandSender> rootNode; var rootNode = CommandNode.rootNode(style, "f", "friend");
public FriendCommand() {
var style = new ScrowMessageStyle(Component.text("Friends")
.color(NamedTextColor.GREEN));
this.rootNode = CommandNode.rootNode(style, "f", "friend");
rootNode.addLiteral(new FriendListLiteral(style).getRootNode()); rootNode.addLiteral(new FriendListLiteral(style).getRootNode());
rootNode.addLiteral(new FriendAddLiteral(style).getRootNode()); rootNode.addLiteral(new FriendAddLiteral(style).getRootNode());
rootNode.addLiteral(new FriendRemoveLiteral(style).getRootNode()); rootNode.addLiteral(new FriendRemoveLiteral(style).getRootNode());

View file

@ -1,12 +1,15 @@
package de.kentoj.scrow.bukkit.friends.command; package de.kentoj.scrow.bukkit.friends.command;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.core.Results;
import de.kentoj.kencommandapi.api.invocation.CommandContext; import de.kentoj.kencommandapi.api.invocation.CommandContext;
import de.kentoj.kencommandapi.api.invocation.CommandExecutor; import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.api.Results;
import de.kentoj.kencommandapi.api.node.CommandNode; import de.kentoj.kencommandapi.api.node.CommandNode;
import de.kentoj.kencommandapi.api.platform.MessageStyle;
import de.kentoj.scrow.bukkit.ScrowAPI; import de.kentoj.scrow.bukkit.ScrowAPI;
import lombok.Getter; import lombok.Getter;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -18,34 +21,42 @@ public class FriendListLiteral implements CommandExecutor<CommandSender> {
@Getter @Getter
private final CommandNode<CommandSender> rootNode; private final CommandNode<CommandSender> rootNode;
private final MessageStyle style;
public FriendListLiteral() { public FriendListLiteral(MessageStyle style) {
this.style = style;
this.rootNode = CommandNode.node("list"); this.rootNode = CommandNode.node("list");
rootNode.setExecutor(this); rootNode.setExecutor(this);
} }
@Override @Override
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) { public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
var sender = (Player) ctx.getSender(); var sender = (Player) ctx.getSender();
var ownUid = sender.getUniqueId(); var ownUid = sender.getUniqueId();
return ScrowAPI.getFriendshipService().getFriendships(ownUid) return CompletableFuture.supplyAsync(() ->
.map(friendship -> Bukkit.getOfflinePlayer(friendship.getUuids().getOther(ownUid))) ScrowAPI.getFriendshipService().getFriendships(ownUid))
.sort(this::compareByOnlineStatus) .thenApply(friendships -> ScrowAPI.getScheduler().sync(() -> {
.collectList() var list = friendships.stream()
.map(list -> { .map(friendship -> Bukkit.getOfflinePlayer(friendship.getUuids().getOther(ownUid)))
if (list.isEmpty()) return Result.error("You have no friends. Use /friend add <player>"); .sorted(this::compareByOnlineStatus)
.toList();
if (list.isEmpty()) return Results.failure("You have no friends. Use /friend add <player>");
var msg = "§3§lFriends§r§7 ☆ You have §3" + list.size() + "§7 friend"; var message = "§7You have §3" + list.size() + "§7" + ("§" +
if (list.size() > 1) msg += "s"; .append(Component.text(list.size() == 1 ? " friend:" : " friends:"));
msg += ":§r\n";
for (var friend : list) { for (var friend : list) {
var status = friend.isOnline() ? "(§aonline§7)" : "(offline)"; message = message.appendNewline();
msg += "§c≫ §7" + friend.getName() + " " + status + "\n"; var status = Component.text("(").append(
friend.isOnline()
? Component.text("online").color(NamedTextColor.GRAY)
: Component.text("offline").color(NamedTextColor.RED))
.append(Component.text(")"));
message = message.append(Component.text("").color(NamedTextColor.AQUA));
} }
sender.sendMessage(msg); sender.sendMessage(msg);
return Result.success(); return Result.success();
}).toFuture(); });
} }
private int compareByOnlineStatus(OfflinePlayer p1, OfflinePlayer p2) { private int compareByOnlineStatus(OfflinePlayer p1, OfflinePlayer p2) {

View file

@ -1,18 +1,20 @@
package de.kentoj.scrow.bukkit.friends.command; package de.kentoj.scrow.bukkit.friends.command;
import de.kentoj.kencommandapi.api.node.CommandNode; import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.core.Results;
import de.kentoj.kencommandapi.api.argument.CommandArgument; import de.kentoj.kencommandapi.api.argument.CommandArgument;
import de.kentoj.kencommandapi.api.invocation.CommandContext; import de.kentoj.kencommandapi.api.invocation.CommandContext;
import de.kentoj.kencommandapi.api.invocation.CommandExecutor; import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
import com.leakyabstractions.result.api.Result; import de.kentoj.kencommandapi.api.node.CommandNode;
import com.leakyabstractions.result.api.Results;
import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType; import de.kentoj.kencommandapi.type.OfflinePlayerArgumentType;
import de.kentoj.scrow.bukkit.ScrowAPI; import de.kentoj.scrow.bukkit.ScrowAPI;
import de.kentoj.scrow.bukkit.scheduler.Tasks;
import lombok.Getter; import lombok.Getter;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class FriendRemoveLiteral implements CommandExecutor<CommandSender> { public class FriendRemoveLiteral implements CommandExecutor<CommandSender> {
@ -20,6 +22,8 @@ public class FriendRemoveLiteral implements CommandExecutor<CommandSender> {
private final CommandNode<CommandSender> rootNode; private final CommandNode<CommandSender> rootNode;
private final CommandArgument<CommandSender, OfflinePlayer> playerArg; private final CommandArgument<CommandSender, OfflinePlayer> playerArg;
private final Scheduler scheduler = ScrowAPI.getScheduler();
public FriendRemoveLiteral() { public FriendRemoveLiteral() {
this.playerArg = CommandArgument.arg("player", OfflinePlayerArgumentType.getInstance()); this.playerArg = CommandArgument.arg("player", OfflinePlayerArgumentType.getInstance());
this.rootNode = CommandNode.node("remove"); this.rootNode = CommandNode.node("remove");
@ -28,15 +32,16 @@ public class FriendRemoveLiteral implements CommandExecutor<CommandSender> {
} }
@Override @Override
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) { public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
var friend = ctx.getArg(playerArg); var friend = ctx.getArg(playerArg);
var player = (Player) ctx.getSender(); var player = (Player) ctx.getSender();
return ScrowAPI.getFriendshipService().deleteFriendship(friend.getUniqueId(), player.getUniqueId()) return Tasks.supplyAsync(() ->
.map(wasAdded -> wasAdded ScrowAPI.getFriendshipService().deleteFriendship(friend.getUniqueId(), player.getUniqueId()))
? Result.success() : Result.error("You are not friends with " + friend.getName()) .<Result<Object, String>>mapSync(deleted -> {
).doOnNext(success -> { if (!deleted)
if (success.isSuccess()) return Results.failure("You are not friends with " + friend.getName());
ctx.getSender().sendMessage("You are no longer friends with " + friend.getName()); ctx.getSender().sendMessage("You have ended the friendship with " + friend.getName());
}).toFuture(); return Results.success(Optional.empty());
}).asFuture();
} }
} }

View file

@ -24,7 +24,7 @@ public class FriendRequestsLiteral implements CommandExecutor<CommandSender> {
} }
@Override @Override
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSender> ctx) { public CompletableFuture<Result<Object,String>> execute(CommandContext<CommandSender> ctx) {
var sender = (Player) ctx.getSender(); var sender = (Player) ctx.getSender();
return ScrowAPI.getFriendRequestService().getFriendRequestsTo(sender.getUniqueId()) return ScrowAPI.getFriendRequestService().getFriendRequestsTo(sender.getUniqueId())
.collectList() .collectList()

View file

@ -1,13 +1,13 @@
package de.kentoj.scrow.bukkit.friends.friendship; package de.kentoj.scrow.bukkit.friends.friendship;
import com.leakyabstractions.result.api.Result;
import com.leakyabstractions.result.core.Results;
import de.kentoj.scrow.bukkit.friends.Friendship; import de.kentoj.scrow.bukkit.friends.Friendship;
import de.kentoj.scrow.bukkit.friends.FriendshipService; import de.kentoj.scrow.bukkit.friends.FriendshipService;
import de.kentoj.scrow.bukkit.friends.OrderedUUIDPair; import de.kentoj.scrow.bukkit.friends.OrderedUUIDPair;
import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@ -16,24 +16,27 @@ public class InMemoryFriendshipService implements FriendshipService {
private final Map<OrderedUUIDPair, Friendship> friendships = new HashMap<>(); private final Map<OrderedUUIDPair, Friendship> friendships = new HashMap<>();
@Override @Override
public Mono<@NotNull Friendship> getFriendship(UUID uuid1, UUID uuid2) { public Result<Friendship, String> getFriendship(UUID uuid1, UUID uuid2) {
return Mono.justOrEmpty(friendships.get(new OrderedUUIDPair(uuid1, uuid2))); return Results.success(friendships.get(new OrderedUUIDPair(uuid1, uuid2)));
} }
@Override @Override
public Flux<@NotNull Friendship> getFriendships(UUID playerId) { public Result<List<Friendship>, String> getFriendships(UUID playerId) {
return Flux.fromStream(friendships.keySet().stream() return Results.success(friendships.entrySet().stream()
.filter(pair -> pair.getFirst().equals(playerId) || pair.getSecond().equals(playerId)) .filter(ent ->
.map(friendships::get)); ent.getKey().getFirst().equals(playerId) || ent.getKey().getSecond().equals(playerId)
)
.map(Map.Entry::getValue)
.toList());
} }
@Override @Override
public Mono<@NotNull Boolean> saveFriendship(Friendship friendship) { public Result<Boolean, String> saveFriendship(Friendship friendship) {
return Mono.just(friendships.putIfAbsent(friendship.getUuids(), friendship) == null); return Results.success(friendships.putIfAbsent(friendship.getUuids(), friendship) == null);
} }
@Override @Override
public Mono<@NotNull Boolean> deleteFriendship(UUID uuid1, UUID uuid2) { public Result<Boolean, String> deleteFriendship(UUID uuid1, UUID uuid2) {
return Mono.just(friendships.remove(new OrderedUUIDPair(uuid1, uuid2)) != null); return Results.success(friendships.remove(new OrderedUUIDPair(uuid1, uuid2)) != null);
} }
} }

View file

@ -1,103 +0,0 @@
package de.kentoj.scrow.bukkit.friends.friendship;
import com.mongodb.ErrorCategory;
import com.mongodb.MongoWriteException;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.IndexOptions;
import com.mongodb.client.model.Indexes;
import com.mongodb.reactivestreams.client.MongoCollection;
import com.mongodb.reactivestreams.client.MongoDatabase;
import de.kentoj.scrow.bukkit.friends.Friendship;
import de.kentoj.scrow.bukkit.friends.FriendshipService;
import de.kentoj.scrow.bukkit.friends.OrderedUUIDPair;
import org.bson.Document;
import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.sql.Date;
import java.util.UUID;
public class MongoFriendshipService implements FriendshipService {
private static final String COLLECTION_NAME = "friendships";
private final MongoDatabase database;
public MongoFriendshipService(MongoDatabase database) {
this.database = database;
Mono.when(
database.createCollection(COLLECTION_NAME),
collection().createIndex(
Indexes.compoundIndex(
Indexes.ascending("first"),
Indexes.ascending("second")
),
new IndexOptions().unique(true))
).block();
}
@Override
public Mono<@NotNull Friendship> getFriendship(UUID uuid1, UUID uuid2) {
var uuids = new OrderedUUIDPair(uuid1, uuid2);
return Mono.from(collection()
.find(Filters.and(
Filters.eq("first", uuids.getFirst()),
Filters.eq("second", uuids.getSecond())
)))
.map(this::fromDocument);
}
@Override
public Flux<@NotNull Friendship> getFriendships(UUID playerId) {
return Flux.from(collection()
.find(Filters.or(
Filters.eq("first", playerId),
Filters.eq("second", playerId)
)))
.map(this::fromDocument);
}
@Override
public Mono<@NotNull Boolean> saveFriendship(Friendship friendship) {
return Mono.from(collection()
.insertOne(toDocument(friendship)))
.thenReturn(true)
.onErrorResume(MongoWriteException.class, e ->
e.getError().getCategory() == ErrorCategory.DUPLICATE_KEY
? Mono.just(Boolean.FALSE)
: Mono.error(e)
);
}
@Override
public Mono<@NotNull Boolean> deleteFriendship(UUID uuid1, UUID uuid2) {
var uuids = new OrderedUUIDPair(uuid1, uuid2);
return Mono.from(collection()
.deleteOne(Filters.and(
Filters.eq("first", uuids.getFirst()),
Filters.eq("second", uuids.getSecond())
)))
.map(res -> res.getDeletedCount() > 0);
}
private MongoCollection<Document> collection() {
return database.getCollection(COLLECTION_NAME);
}
private Friendship fromDocument(Document doc) {
return new FriendshipImpl(
doc.get("first", UUID.class),
doc.get("second", UUID.class),
doc.getDate("createdAt").toInstant()
);
}
private Document toDocument(Friendship friendship) {
return new Document()
.append("first", friendship.getUuids().getFirst())
.append("second", friendship.getUuids().getSecond())
.append("createdAt", Date.from(friendship.getCreatedAt()));
}
}

View file

@ -30,7 +30,7 @@ public class PostgresFriendshipService implements FriendshipService {
} }
@Override @Override
public Mono<@NotNull Friendship> getFriendship(UUID uuid1, UUID uuid2) { public Result<Friendship, String> getFriendship(UUID uuid1, UUID uuid2) {
var uuids = new OrderedUUIDPair(uuid1, uuid2); var uuids = new OrderedUUIDPair(uuid1, uuid2);
return dbConFactory.create().sql(""" return dbConFactory.create().sql("""
@ -49,7 +49,7 @@ public class PostgresFriendshipService implements FriendshipService {
} }
@Override @Override
public Flux<@NotNull Friendship> getFriendships(UUID playerId) { public Result<List<Friendship>, String> getFriendships(UUID playerId) {
return dbConFactory.create().sql(""" return dbConFactory.create().sql("""
SELECT first_uuid, second_uuid, created_at SELECT first_uuid, second_uuid, created_at
FROM friendships FROM friendships
@ -65,7 +65,7 @@ public class PostgresFriendshipService implements FriendshipService {
} }
@Override @Override
public Mono<@NotNull Boolean> saveFriendship(Friendship friendship) { public Result<Boolean, String> saveFriendship(Friendship friendship) {
return dbConFactory.create().sql(""" return dbConFactory.create().sql("""
INSERT INTO friendships (first_uuid, second_uuid, created_at) INSERT INTO friendships (first_uuid, second_uuid, created_at)
VALUES (:first, :second, :createdAt) VALUES (:first, :second, :createdAt)
@ -80,7 +80,7 @@ public class PostgresFriendshipService implements FriendshipService {
} }
@Override @Override
public Mono<@NotNull Boolean> deleteFriendship(UUID uuid1, UUID uuid2) { public Result<Boolean, String> deleteFriendship(UUID uuid1, UUID uuid2) {
var uuids = new OrderedUUIDPair(uuid1, uuid2); var uuids = new OrderedUUIDPair(uuid1, uuid2);
return dbConFactory.create().sql(""" return dbConFactory.create().sql("""

View file

@ -2,11 +2,9 @@ package de.kentoj.scrow.bukkit.friends.request;
import de.kentoj.scrow.bukkit.friends.FriendRequest; import de.kentoj.scrow.bukkit.friends.FriendRequest;
import de.kentoj.scrow.bukkit.friends.FriendRequestService; import de.kentoj.scrow.bukkit.friends.FriendRequestService;
import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -15,34 +13,34 @@ public class InMemoryFriendRequestService implements FriendRequestService {
private final Set<FriendRequest> requests = new HashSet<>(); private final Set<FriendRequest> requests = new HashSet<>();
@Override @Override
public Flux<@NotNull FriendRequest> getFriendRequestsTo(UUID playerId) { public List<FriendRequest> getFriendRequestsTo(UUID playerId) {
return Flux.fromStream(requests.stream() return requests.stream()
.filter(req -> req.getTo().equals(playerId))); .filter(req -> req.getTo().equals(playerId))
.toList();
} }
@Override @Override
public Flux<@NotNull FriendRequest> getFriendRequestsFrom(UUID playerId) { public List<FriendRequest> getFriendRequestsFrom(UUID playerId) {
return Flux.fromStream(requests.stream() return requests.stream()
.filter(req -> req.getFrom().equals(playerId))); .filter(req -> req.getFrom().equals(playerId))
.toList();
} }
@Override @Override
public Mono<@NotNull FriendRequest> getFriendRequest(UUID from, UUID to) { public FriendRequest getFriendRequest(UUID from, UUID to) {
return Mono.justOrEmpty(requests.stream() return requests.stream()
.filter(req -> req.getFrom().equals(from) && req.getTo().equals(to)) .filter(req -> req.getFrom().equals(from) && req.getTo().equals(to))
.findFirst() .findFirst()
.orElse(null)); .orElse(null);
} }
@Override @Override
public Mono<@NotNull Boolean> saveFriendRequest(FriendRequest friendRequest) { public boolean saveFriendRequest(FriendRequest friendRequest) {
return getFriendRequest(friendRequest.getFrom(), friendRequest.getTo()) return requests.add(friendRequest);
.map(__ -> false)
.switchIfEmpty(Mono.fromRunnable(() -> requests.add(friendRequest)));
} }
@Override @Override
public Mono<@NotNull Boolean> deleteFriendRequest(UUID from, UUID to) { public boolean deleteFriendRequest(UUID from, UUID to) {
return Mono.just(requests.removeIf(req -> req.getFrom().equals(from) && req.getTo().equals(to))); return requests.removeIf(req -> req.getFrom().equals(from) && req.getTo().equals(to));
} }
} }

View file

@ -1,107 +0,0 @@
package de.kentoj.scrow.bukkit.friends.request;
import com.mongodb.ErrorCategory;
import com.mongodb.MongoWriteException;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.IndexOptions;
import com.mongodb.client.model.Indexes;
import com.mongodb.reactivestreams.client.MongoCollection;
import com.mongodb.reactivestreams.client.MongoDatabase;
import de.kentoj.scrow.bukkit.friends.FriendRequest;
import de.kentoj.scrow.bukkit.friends.FriendRequestService;
import org.bson.Document;
import org.jetbrains.annotations.NotNull;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Date;
import java.util.UUID;
public class MongoFriendRequestService implements FriendRequestService {
private static final String COLLECTION_NAME = "friend-requests";
private final MongoDatabase database;
public MongoFriendRequestService(MongoDatabase database) {
this.database = database;
Mono.when(
database.createCollection(COLLECTION_NAME),
collection().createIndex(
Indexes.compoundIndex(
Indexes.ascending("from"),
Indexes.ascending("to")
),
new IndexOptions().unique(true)
)
).block();
}
@Override
public Mono<@NotNull FriendRequest> getFriendRequest(UUID from, UUID to) {
return Mono.from(collection()
.find(Filters.and(
Filters.eq("from", from),
Filters.eq("to", to)
)))
.map(this::fromDocument);
}
@Override
public Mono<@NotNull Boolean> saveFriendRequest(FriendRequest friendRequest) {
return Mono.from(collection()
.insertOne(toDocument(friendRequest))
)
.map(__ -> true)
.onErrorResume(MongoWriteException.class, e ->
e.getError().getCategory() == ErrorCategory.DUPLICATE_KEY ?
Mono.just(false) :
Mono.error(e)
);
}
@Override
public Flux<@NotNull FriendRequest> getFriendRequestsTo(UUID playerId) {
return Flux.from(collection()
.find(Filters.eq("to", playerId)))
.map(this::fromDocument);
}
@Override
public Flux<@NotNull FriendRequest> getFriendRequestsFrom(UUID playerId) {
return Flux.from(collection()
.find()
.filter(Filters.eq("from", playerId)))
.map(this::fromDocument);
}
@Override
public Mono<@NotNull Boolean> deleteFriendRequest(UUID from, UUID to) {
return Mono.from(collection()
.deleteOne(Filters.and(
Filters.eq("from", from),
Filters.eq("to", to)
)))
.map(res -> res.getDeletedCount() > 0);
}
private MongoCollection<Document> collection() {
return database.getCollection(COLLECTION_NAME);
}
private Document toDocument(FriendRequest req) {
return new Document()
.append("from", req.getFrom())
.append("to", req.getTo())
.append("createdAt", Date.from(req.getCreatedAt()));
}
private FriendRequest fromDocument(Document doc) {
return new FriendRequestImpl(
doc.get("from", UUID.class),
doc.get("to", UUID.class),
doc.getDate("createdAt").toInstant()
);
}
}

View file

@ -31,7 +31,7 @@ public class PostgresFriendRequestService implements FriendRequestService {
} }
@Override @Override
public Mono<@NotNull FriendRequest> getFriendRequest(UUID from, UUID to) { public Result<FriendRequest, String> getFriendRequest(UUID from, UUID to) {
return conFactory.create().sql(""" return conFactory.create().sql("""
SELECT * SELECT *
FROM friend-requests FROM friend-requests
@ -44,7 +44,7 @@ public class PostgresFriendRequestService implements FriendRequestService {
} }
@Override @Override
public Mono<@NotNull Boolean> saveFriendRequest(FriendRequest friendRequest) { public Result<Boolean, String> saveFriendRequest(FriendRequest friendRequest) {
return conFactory.create().sql(""" return conFactory.create().sql("""
INSERT INTO friend-requests (from_uuid, to_uuid, created_at) INSERT INTO friend-requests (from_uuid, to_uuid, created_at)
VALUES (:from, :to, :created_at) VALUES (:from, :to, :created_at)
@ -57,7 +57,7 @@ public class PostgresFriendRequestService implements FriendRequestService {
} }
@Override @Override
public Flux<@NotNull FriendRequest> getFriendRequestsTo(UUID playerId) { public Result<List<FriendRequest>, String> getFriendRequestsTo(UUID playerId) {
return conFactory.create().sql(""" return conFactory.create().sql("""
SELECT * SELECT *
FROM friend-requests FROM friend-requests
@ -69,7 +69,7 @@ public class PostgresFriendRequestService implements FriendRequestService {
} }
@Override @Override
public Flux<@NotNull FriendRequest> getFriendRequestsFrom(UUID playerId) { public Result<List<FriendRequest>, String> getFriendRequestsFrom(UUID playerId) {
return conFactory.create().sql(""" return conFactory.create().sql("""
SELECT * SELECT *
FROM friend-requests FROM friend-requests
@ -81,7 +81,7 @@ public class PostgresFriendRequestService implements FriendRequestService {
} }
@Override @Override
public Mono<@NotNull Boolean> deleteFriendRequest(UUID from, UUID to) { public Result<Boolean, String> deleteFriendRequest(UUID from, UUID to) {
return conFactory.create().sql(""" return conFactory.create().sql("""
DELETE DELETE
FROM friend-requests FROM friend-requests

View file

@ -1,7 +1,7 @@
package de.kentoj.scrow.bukkit.playermanager; package de.kentoj.scrow.bukkit.playermanager;
import com.leakyabstractions.result.api.Result; import com.leakyabstractions.result.api.Result;
import de.kentoj.scrow.bukkit.PlayerManager; import de.kentoj.scrow.bukkit.misc.PlayerManager;
import de.kentoj.scrowlib.messaging.MessageBroker; import de.kentoj.scrowlib.messaging.MessageBroker;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.bson.Document; import org.bson.Document;
@ -14,7 +14,7 @@ public class PlayerManagerImpl implements PlayerManager {
private final MessageBroker messageBroker; private final MessageBroker messageBroker;
@Override @Override
public Result<Void, String> sendPlayer(UUID playerId, String instanceHandle) { public Result<Object, String> sendPlayer(UUID playerId, String instanceHandle) {
return messageBroker.request("players.send", new Document() return messageBroker.request("players.send", new Document()
.append("playerId", playerId) .append("playerId", playerId)
.append("handle", instanceHandle)) .append("handle", instanceHandle))

View file

@ -22,7 +22,7 @@ public class LobbyCommand implements CommandExecutor<CommandSender> {
} }
@Override @Override
public CompletableFuture<Result<Void, String>> execute(CommandContext<CommandSender> ctx) { public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
Bukkit.dispatchCommand(ctx.getSender(), "play lobby"); Bukkit.dispatchCommand(ctx.getSender(), "play lobby");
return CompletableFuture.completedFuture(Results.success(null)); return CompletableFuture.completedFuture(Results.success(null));
} }

View file

@ -28,7 +28,7 @@ public class PlayCommand implements CommandExecutor<CommandSender> {
} }
@Override @Override
public CompletableFuture<Result<Void, String>> execute(CommandContext<CommandSender> ctx) { public CompletableFuture<Result<Object, String>> execute(CommandContext<CommandSender> ctx) {
var gamemode = ctx.getArg(gamemodeArg); var gamemode = ctx.getArg(gamemodeArg);
var player = (Player) ctx.getSender(); var player = (Player) ctx.getSender();
return CompletableFuture.supplyAsync(() -> ScrowAPI.getInstanceManager().getInstances() return CompletableFuture.supplyAsync(() -> ScrowAPI.getInstanceManager().getInstances()

View file

@ -23,7 +23,7 @@ dependencies {
api("org.mongodb:bson:5.8.0") api("org.mongodb:bson:5.8.0")
// http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-core // http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-core
api("de.kentoj.scrow:kencommandapi-core:0.21") api("de.kentoj.scrow:kencommandapi-core:0.22")
} }
publishing { publishing {

View file

@ -12,7 +12,7 @@ public interface InstanceManager {
*/ */
Result<ServerInstance, String> deployInstance(String template); Result<ServerInstance, String> deployInstance(String template);
Result<Void, String> destroyInstance(String handle); Result<Object, String> destroyInstance(String handle);
/** /**
* @return Flux with handles of running servers * @return Flux with handles of running servers

View file

@ -23,7 +23,7 @@ public class InstanceManagerImpl implements InstanceManager {
} }
@Override @Override
public Result<Void, String> destroyInstance(String handle) { public Result<Object, String> destroyInstance(String handle) {
var result = messageBroker.request("instance.destroy", new Document("handle", handle)); var result = messageBroker.request("instance.destroy", new Document("handle", handle));
return result.mapSuccess(__ -> null); return result.mapSuccess(__ -> null);
} }

View file

@ -24,9 +24,9 @@ dependencies {
api("com.velocitypowered:velocity-api:3.5.0-SNAPSHOT") api("com.velocitypowered:velocity-api:3.5.0-SNAPSHOT")
// http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-core // http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-core
api("de.kentoj.scrow:kencommandapi-core:0.21") api("de.kentoj.scrow:kencommandapi-core:0.22")
// http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-velocity // http://forge.kentoj.de/scrow/-/packages/maven/de.kentoj.scrow:kencommandapi-velocity
api("de.kentoj.scrow:kencommandapi-velocity:0.21") api("de.kentoj.scrow:kencommandapi-velocity:0.22")
} }
publishing { publishing {

View file

@ -28,7 +28,7 @@ public class OnlineCommand implements CommandExecutor<CommandSource> {
} }
@Override @Override
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSource> ctx) { public CompletableFuture<Result<Object,String>> execute(CommandContext<CommandSource> ctx) {
int cnt = server.getPlayerCount(); int cnt = server.getPlayerCount();
var msg = cnt != 1 var msg = cnt != 1
? "There are currently " + cnt + " players online" ? "There are currently " + cnt + " players online"

View file

@ -37,7 +37,7 @@ public class MsgCommand implements CommandExecutor<CommandSource> {
} }
@Override @Override
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSource> ctx) { public CompletableFuture<Result<Object,String>> execute(CommandContext<CommandSource> ctx) {
var target = ctx.getArg(targetArg); var target = ctx.getArg(targetArg);
var msg = ctx.getArg(msgArg); var msg = ctx.getArg(msgArg);
var sender = (Player)ctx.getSender(); var sender = (Player)ctx.getSender();

View file

@ -34,7 +34,7 @@ public class ReplyCommand implements CommandExecutor<CommandSource> {
} }
@Override @Override
public CompletableFuture<Result<Void,String>> execute(CommandContext<CommandSource> ctx) { public CompletableFuture<Result<Object,String>> execute(CommandContext<CommandSource> ctx) {
var sender = (Player)ctx.getSender(); var sender = (Player)ctx.getSender();
var targetId = cache.getLastTarget(sender.getUniqueId()); var targetId = cache.getLastTarget(sender.getUniqueId());
var target = server.getPlayer(targetId).orElse(null); var target = server.getPlayer(targetId).orElse(null);

View file

@ -39,7 +39,7 @@ public class ServerRegisterWatchdog {
.subscribe(null, e -> log.throwing(getClass().getName(), "listen", e)); .subscribe(null, e -> log.throwing(getClass().getName(), "listen", e));
} }
private @NotNull Mono<@NotNull Void> handleStateChange(SubscriptionContext ctx, String state, String handle) { private @NotNull Result<Object, String> handleStateChange(SubscriptionContext ctx, String state, String handle) {
return switch (state) { return switch (state) {
case "UP" -> instanceManager.getInfo(handle) case "UP" -> instanceManager.getInfo(handle)
.doOnNext(instance -> .doOnNext(instance ->