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")
}
}