diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index f86c6c165..431339d48 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -35,6 +35,8 @@ object Versions { const val TRIUMPH_GUI = "3.1.11" + const val LUCKPERMS = "5.4.156" + const val BSTATS = "3.1.0" const val CAFFEINE = "3.2.0" diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleport/command/TeleportBackCommand.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleport/command/TeleportBackCommand.java index dc9dfa4a1..f9b0956e7 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleport/command/TeleportBackCommand.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleport/command/TeleportBackCommand.java @@ -1,15 +1,18 @@ package com.eternalcode.core.feature.teleport.command; import com.eternalcode.annotations.scan.command.DescriptionDocs; +import com.eternalcode.commons.bukkit.position.PositionAdapter; +import com.eternalcode.core.feature.teleport.TeleportService; +import com.eternalcode.core.feature.teleport.TeleportTaskService; +import com.eternalcode.core.feature.teleportrequest.TeleportRequestSettings; import com.eternalcode.core.injector.annotations.Inject; import com.eternalcode.core.notice.NoticeService; -import com.eternalcode.core.feature.teleport.TeleportService; import com.eternalcode.core.viewer.Viewer; import dev.rollczi.litecommands.annotations.argument.Arg; +import dev.rollczi.litecommands.annotations.command.Command; import dev.rollczi.litecommands.annotations.context.Context; import dev.rollczi.litecommands.annotations.execute.Execute; import dev.rollczi.litecommands.annotations.permission.Permission; -import dev.rollczi.litecommands.annotations.command.Command; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -19,11 +22,15 @@ class TeleportBackCommand { private final TeleportService teleportService; + private final TeleportTaskService teleportTaskService; + private final TeleportRequestSettings settings; private final NoticeService noticeService; @Inject - TeleportBackCommand(TeleportService teleportService, NoticeService noticeService) { + TeleportBackCommand(TeleportService teleportService, TeleportTaskService teleportTaskService, TeleportRequestSettings settings, NoticeService noticeService) { this.teleportService = teleportService; + this.teleportTaskService = teleportTaskService; + this.settings = settings; this.noticeService = noticeService; } @@ -39,7 +46,12 @@ void execute(@Context Player player) { return; } - this.teleportService.teleport(player, location.get()); + if (player.hasPermission("eternalcore.teleport.bypass")) { + this.teleportService.teleport(player, location.get()); + } else { + this.teleportTaskService.createTeleport(player.getUniqueId(), PositionAdapter.convert(player.getLocation()), PositionAdapter.convert(location.get()), this.settings.teleportTime()); + } + this.noticeService.player(player.getUniqueId(), translation -> translation.teleport().teleportedToLastLocation()); } @@ -55,7 +67,11 @@ void execute(@Context Viewer viewer, @Arg Player player) { return; } - this.teleportService.teleport(player, location.get()); + if (player.hasPermission("eternalcore.teleport.bypass")){ + this.teleportService.teleport(player, location.get()); + } else { + this.teleportTaskService.createTeleport(player.getUniqueId(), PositionAdapter.convert(player.getLocation()), PositionAdapter.convert(location.get()), this.settings.teleportTime()); + } this.noticeService.player(player.getUniqueId(), translation -> translation.teleport().teleportedToLastLocation()); diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/messages/ENTeleportRequestMessages.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/messages/ENTeleportRequestMessages.java index 1a72ebf12..df187240d 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/messages/ENTeleportRequestMessages.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/messages/ENTeleportRequestMessages.java @@ -14,7 +14,16 @@ public class ENTeleportRequestMessages implements TeleportRequestMessages { public Notice tpaAlreadySentMessage = Notice.chat("You have already sent a teleportation request!"); public Notice tpaSentMessage = - Notice.chat("You have sent a request for teleportation to a player: {PLAYER}!"); + Notice.chat("You have sent a request for player {PLAYER}{PLAYER} to teleport to you!"); + + public Notice tpaHereSentMessage = Notice.chat("You have sent a request for teleportation to you for a player: {PLAYER}!"); + public Notice tpaHereReceivedMessage = Notice.builder() + .chat("You have received a request for teleportation TO a player: {PLAYER}!") + .chat( + "Teleport to the player?'>» /tpahereaccept {PLAYER} to accept! (Click)") + .chat( + "Decline a teleportation request?'>» /tpaheredeny {PLAYER} to deny! (Click)") + .build(); @Description({ " ", diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/messages/PLTeleportRequestMessages.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/messages/PLTeleportRequestMessages.java index 8bdb73462..ac79a8acf 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/messages/PLTeleportRequestMessages.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/messages/PLTeleportRequestMessages.java @@ -16,6 +16,14 @@ public class PLTeleportRequestMessages implements TeleportRequestMessages { public Notice tpaSentMessage = Notice.chat("Wysłałeś prośbę o teleportację do gracza: {PLAYER}!"); + public Notice tpaHereSentMessage = Notice.chat("Wysłałeś prośbę o teleportację gracza {PLAYER} do twojej lokalizacji!"); + public Notice tpaHereReceivedMessage = Notice.builder() + .chat("Otrzymałeś prośbę o teleportację do gracza: {PLAYER}!") + .chat( + "Teleportować się do gracza?'>» /tpahereaccept {PLAYER} by ją zaakceptować! (Kliknij)") + .chat( + "Odrzucić prośbę o teleportacje?'>» /tpaheredeny {PLAYER} by ją odrzucić! (Kliknij)") + .build(); @Description({ " ", "# W tych wiadomościach użyliśmy formatowania MiniMessages", diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/messages/TeleportRequestMessages.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/messages/TeleportRequestMessages.java index d45d45189..b3eb1f248 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/messages/TeleportRequestMessages.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/messages/TeleportRequestMessages.java @@ -9,6 +9,9 @@ public interface TeleportRequestMessages { Notice tpaReceivedMessage(); Notice tpaTargetIgnoresYou(); + Notice tpaHereSentMessage(); + Notice tpaHereReceivedMessage(); + Notice tpaDenyNoRequestMessage(); Notice tpaDenyDoneMessage(); Notice tpaDenyReceivedMessage(); diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/self/SelfRequesterArgument.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/self/SelfRequesterArgument.java new file mode 100644 index 000000000..7b0f51706 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/self/SelfRequesterArgument.java @@ -0,0 +1,63 @@ +package com.eternalcode.core.feature.teleportrequest.self; + +import com.eternalcode.core.bridge.litecommand.argument.AbstractViewerArgument; +import com.eternalcode.core.injector.annotations.Inject; +import com.eternalcode.core.injector.annotations.lite.LiteArgument; +import com.eternalcode.core.translation.Translation; +import com.eternalcode.core.translation.TranslationManager; +import dev.rollczi.litecommands.argument.Argument; +import dev.rollczi.litecommands.argument.parser.ParseResult; +import dev.rollczi.litecommands.invocation.Invocation; +import dev.rollczi.litecommands.suggestion.SuggestionContext; +import dev.rollczi.litecommands.suggestion.SuggestionResult; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; + +import java.util.Objects; + +@LiteArgument(type = Player.class, name = SelfRequesterArgument.KEY) +class SelfRequesterArgument extends AbstractViewerArgument { + + static final String KEY = "selfrequester"; + + private final TeleportHereRequestService requestService; + private final Server server; + + @Inject + SelfRequesterArgument(TeleportHereRequestService requestService, TranslationManager translationManager, Server server) { + super(translationManager); + this.requestService = requestService; + this.server = server; + } + + @Override + public ParseResult parse(Invocation invocation, String argument, Translation translation) { + Player target = this.server.getPlayer(argument); + + if (!(invocation.sender() instanceof Player player)) { + return ParseResult.failure(translation.argument().onlyPlayer()); + } + + if (target == null || !this.requestService.hasRequest(target.getUniqueId(), player.getUniqueId())) { + return ParseResult.failure(translation.tpa().tpaDenyNoRequestMessage()); + } + + return ParseResult.success(target); + } + + @Override + public SuggestionResult suggest(Invocation invocation, Argument argument, SuggestionContext context) { + if (!(invocation.sender() instanceof Player player)) { + return SuggestionResult.empty(); + } + + return this.requestService.findRequests(player.getUniqueId()).stream() + .map(this.server::getPlayer) + .filter(Objects::nonNull) + .map(HumanEntity::getName) + .collect(SuggestionResult.collector()); + } + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/self/TeleportHereRequestService.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/self/TeleportHereRequestService.java new file mode 100644 index 000000000..d15045bc1 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/self/TeleportHereRequestService.java @@ -0,0 +1,61 @@ +package com.eternalcode.core.feature.teleportrequest.self; + +import com.eternalcode.core.feature.teleportrequest.TeleportRequestSettings; +import com.eternalcode.core.injector.annotations.Inject; +import com.eternalcode.core.injector.annotations.component.Service; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +@Service +class TeleportHereRequestService { + + private final Cache requests; + + @Inject + TeleportHereRequestService(TeleportRequestSettings settings) { + this.requests = CacheBuilder + .newBuilder() + .expireAfterWrite(settings.teleportExpire()) + .build(); + } + + void createRequest(UUID requester, UUID target) { + this.requests.put(requester, target); + } + + void removeRequest(UUID requester) { + this.requests.asMap().remove(requester); + } + + boolean hasRequest(UUID requester, UUID target) { + Map map = this.requests.asMap(); + + for (Map.Entry entry : map.entrySet()) { + if (entry.getKey().equals(requester) && entry.getValue().equals(target)) { + return true; + } + } + + return false; + } + + List findRequests(UUID target) { + Map map = this.requests.asMap(); + + List requesters = new ArrayList<>(); + + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue().equals(target)) { + requesters.add(entry.getKey()); + } + } + + return requesters; + } + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/self/TpaHereActionCommand.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/self/TpaHereActionCommand.java new file mode 100644 index 000000000..caf263665 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/self/TpaHereActionCommand.java @@ -0,0 +1,114 @@ +package com.eternalcode.core.feature.teleportrequest.self; + +import com.eternalcode.annotations.scan.command.DescriptionDocs; +import com.eternalcode.commons.bukkit.position.PositionAdapter; +import com.eternalcode.core.feature.teleport.TeleportTaskService; +import com.eternalcode.core.feature.teleportrequest.TeleportRequestSettings; +import com.eternalcode.core.injector.annotations.Inject; +import com.eternalcode.core.notice.NoticeService; +import dev.rollczi.litecommands.annotations.argument.Arg; +import dev.rollczi.litecommands.annotations.command.RootCommand; +import dev.rollczi.litecommands.annotations.context.Context; +import dev.rollczi.litecommands.annotations.execute.Execute; +import dev.rollczi.litecommands.annotations.permission.Permission; +import org.bukkit.Server; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.UUID; + +@RootCommand +class TpaHereActionCommand { + + private final TeleportHereRequestService requestService; + private final TeleportTaskService teleportTaskService; + private final TeleportRequestSettings settings; + private final NoticeService noticeService; + private final Server server; + + @Inject + TpaHereActionCommand(TeleportHereRequestService requestService, TeleportTaskService teleportTaskService, TeleportRequestSettings settings, NoticeService noticeService, Server server) { + this.requestService = requestService; + this.teleportTaskService = teleportTaskService; + this.settings = settings; + this.noticeService = noticeService; + this.server = server; + } + + @Execute(name = "tpahereaccept") + @Permission("eternalcore.tpaccept") + void accept(@Context Player player, @Arg(SelfRequesterArgument.KEY) Player target) { + this.teleportTaskService.createTeleport( + player.getUniqueId(), + PositionAdapter.convert(player.getLocation()), + PositionAdapter.convert(target.getLocation()), + this.settings.teleportTime() + ); + + this.requestService.removeRequest(target.getUniqueId()); + + this.noticeService + .create() + .player(player.getUniqueId()) + .notice(translation -> translation.tpa().tpaAcceptMessage()) + .placeholder("{PLAYER}", target.getName()) + .send(); + + this.noticeService + .create() + .player(target.getUniqueId()) + .notice(translation -> translation.tpa().tpaAcceptReceivedMessage()) + .placeholder("{PLAYER}", player.getName()) + .send(); + } + + @Execute(name = "tpaheredeny") + @Permission("eternalcore.tpahere.deny") + @DescriptionDocs(description = "Deny a teleport here request") + void executeTarget(@Context Player player, @Arg(SelfRequesterArgument.KEY) Player target) { + this.requestService.removeRequest(target.getUniqueId()); + + this.noticeService + .create() + .player(player.getUniqueId()) + .notice(translation -> translation.tpa().tpaDenyDoneMessage()) + .placeholder("{PLAYER}", target.getName()) + .send(); + + this.noticeService + .create() + .player(target.getUniqueId()) + .notice(translation -> translation.tpa().tpaDenyReceivedMessage()) + .placeholder("{PLAYER}", player.getName()) + .send(); + } + + @Execute(name = "tpaheredeny -all") + @Permission("eternalcore.tpahere.deny") + @DescriptionDocs(description = "Deny all teleport here requests") + void executeAll(@Context Player player) { + List requests = this.requestService.findRequests(player.getUniqueId()); + + if (requests.isEmpty()) { + this.noticeService.player(player.getUniqueId(), translation -> translation.tpa().tpaDenyNoRequestMessage()); + return; + } + + for (UUID uniqueId : requests) { + Player requester = this.server.getPlayer(uniqueId); + this.requestService.removeRequest(uniqueId); + + if (requester != null) { + this.noticeService + .create() + .player(uniqueId) + .notice(translation -> translation.tpa().tpaDenyReceivedMessage()) + .placeholder("{PLAYER}", player.getName()) + .send(); + } + } + + this.noticeService.player(player.getUniqueId(), translation -> translation.tpa().tpaDenyAllDenied()); + } + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/self/TpaHereCommand.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/self/TpaHereCommand.java new file mode 100644 index 000000000..3553a2395 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrequest/self/TpaHereCommand.java @@ -0,0 +1,74 @@ +package com.eternalcode.core.feature.teleportrequest.self; + +import com.eternalcode.core.feature.ignore.IgnoreService; +import com.eternalcode.core.injector.annotations.Inject; +import com.eternalcode.core.notice.NoticeService; +import dev.rollczi.litecommands.annotations.argument.Arg; +import dev.rollczi.litecommands.annotations.command.Command; +import dev.rollczi.litecommands.annotations.context.Context; +import dev.rollczi.litecommands.annotations.execute.Execute; +import dev.rollczi.litecommands.annotations.permission.Permission; +import org.bukkit.entity.Player; + +import java.util.concurrent.CompletableFuture; + +@Command(name = "tpahere") +@Permission("eternalcore.tpahere") +class TpaHereCommand { + + private final TeleportHereRequestService requestService; + private final IgnoreService ignoreService; + private final NoticeService noticeService; + + @Inject + TpaHereCommand(TeleportHereRequestService requestService, IgnoreService ignoreService, NoticeService noticeService) { + this.requestService = requestService; + this.ignoreService = ignoreService; + this.noticeService = noticeService; + } + + @Execute + void execute(@Context Player sender, @Arg Player target) { + if (sender.equals(target)) { + this.noticeService.player(sender.getUniqueId() , translation -> translation.tpa().tpaSelfMessage()); + + return; + } + + if (this.requestService.hasRequest(sender.getUniqueId(), target.getUniqueId())) { + this.noticeService.player(sender.getUniqueId(), translation -> translation.tpa().tpaAlreadySentMessage()); + + return; + } + + this.isIgnoring(target, sender).thenAccept(isIgnoring -> { + if (isIgnoring) { + this.noticeService.create() + .player(sender.getUniqueId()) + .notice(translation -> translation.tpa().tpaTargetIgnoresYou()) + .placeholder("{PLAYER}", target.getName()) + .send(); + return; + } + + this.noticeService + .create() + .player(sender.getUniqueId()) + .notice(translation -> translation.tpa().tpaSentMessage()) + .placeholder("{PLAYER}", target.getName()) + .send(); + + this.noticeService.create() + .player(target.getUniqueId()) + .notice(translation -> translation.tpa().tpaHereReceivedMessage()) + .placeholder("{PLAYER}", sender.getName()) + .send(); + + this.requestService.createRequest(sender.getUniqueId(), target.getUniqueId()); + }); + } + + private CompletableFuture isIgnoring(Player target, Player sender) { + return this.ignoreService.isIgnored(target.getUniqueId(), sender.getUniqueId()); + } +} diff --git a/eternalcore-plugin/build.gradle.kts b/eternalcore-plugin/build.gradle.kts index 9ac557482..caabfd571 100644 --- a/eternalcore-plugin/build.gradle.kts +++ b/eternalcore-plugin/build.gradle.kts @@ -39,5 +39,6 @@ dependencies { tasks { runServer { minecraftVersion("1.21.4") + downloadPlugins.url("https://ci.lucko.me/job/LuckPerms/lastBuild/artifact/bukkit/loader/build/libs/LuckPerms-Bukkit-${Versions.LUCKPERMS}.jar") } }