diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/configuration/migrations/Migration_0010_Move_back_to_dedicated_section.java b/eternalcore-core/src/main/java/com/eternalcode/core/configuration/migrations/Migration_0010_Move_back_to_dedicated_section.java new file mode 100644 index 000000000..e627ca0a5 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/configuration/migrations/Migration_0010_Move_back_to_dedicated_section.java @@ -0,0 +1,17 @@ +package com.eternalcode.core.configuration.migrations; + +import eu.okaeri.configs.migrate.builtin.NamedMigration; + +import static eu.okaeri.configs.migrate.ConfigMigrationDsl.move; + +public class Migration_0010_Move_back_to_dedicated_section extends NamedMigration { + Migration_0010_Move_back_to_dedicated_section() { + super( + "Improve homes config", + move("teleport.teleportedToLastLocation", "back.teleportedToLastLocation"), + move("teleport.teleportedSpecifiedPlayerLastLocation", "back.teleportedSpecifiedPlayerLastLocation"), + move("teleport.lastLocationNoExist", "back.lastLocationNoExist") + ); + } +} + diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/BackCommand.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/BackCommand.java new file mode 100644 index 000000000..f6ed7f624 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/BackCommand.java @@ -0,0 +1,104 @@ +package com.eternalcode.core.feature.back; + +import com.eternalcode.annotations.scan.command.DescriptionDocs; +import com.eternalcode.core.feature.back.BackService.BackLocation; +import com.eternalcode.core.injector.annotations.Inject; +import com.eternalcode.core.notice.NoticeService; +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.Sender; +import dev.rollczi.litecommands.annotations.execute.Execute; +import dev.rollczi.litecommands.annotations.permission.Permission; +import java.util.Optional; +import org.bukkit.entity.Player; +import panda.std.Pair; + +@Command(name = "back") +public class BackCommand { + + private final BackService backService; + private final NoticeService noticeService; + + @Inject + public BackCommand(BackService backService, NoticeService noticeService) { + this.backService = backService; + this.noticeService = noticeService; + } + + @Execute(name = "death") + @Permission("eternalcore.back.death") + @DescriptionDocs(description = "Teleport to your last death location") + public void executeBackDeath(@Sender Player player) { + Optional> backPair = this.backService.getBackLocationPair(player.getUniqueId()); + + if (backPair.isEmpty() || backPair.get().getFirst() == null) { + this.noticeService.player(player.getUniqueId(), translation -> translation.back().lastLocationNoExist()); + return; + } + + BackLocation deathLocation = backPair.get().getFirst(); + this.backService.teleportBack(player, deathLocation.location()); + this.noticeService.player(player.getUniqueId(), translation -> translation.back().teleportedToLastLocation()); + } + + @Execute(name = "teleport") + @Permission("eternalcore.back.teleport") + @DescriptionDocs(description = "Teleport to your last teleport location") + public void executeBackTeleport(@Sender Player player) { + Optional> backPair = this.backService.getBackLocationPair(player.getUniqueId()); + + if (backPair.isEmpty() || backPair.get().getSecond() == null) { + this.noticeService.player(player.getUniqueId(), translation -> translation.back().lastLocationNoExist()); + return; + } + + BackLocation teleportLocation = backPair.get().getSecond(); + this.backService.teleportBack(player, teleportLocation.location()); + this.noticeService.player(player.getUniqueId(), translation -> translation.back().teleportedToLastLocation()); + } + + @Execute(name = "death") + @Permission("eternalcore.back.death.other") + @DescriptionDocs(description = "Teleport specified player to their last death location", arguments = "") + public void executeBackDeathOther(@Sender Viewer viewer, @Arg Player target) { + Optional> backPair = this.backService.getBackLocationPair(target.getUniqueId()); + + if (backPair.isEmpty() || backPair.get().getFirst() == null) { + this.noticeService.viewer(viewer, translation -> translation.back().lastLocationNoExist()); + return; + } + + BackLocation deathLocation = backPair.get().getFirst(); + this.backService.teleportBack(target, deathLocation.location()); + this.noticeService.player(target.getUniqueId(), translation -> translation.back().teleportedToLastLocation()); + + this.noticeService.create() + .viewer(viewer) + .notice(translation -> translation.back().teleportedSpecifiedPlayerLastLocation()) + .placeholder("{PLAYER}", target.getName()) + .send(); + } + + @Execute(name = "teleport") + @Permission("eternalcore.back.teleport.other") + @DescriptionDocs(description = "Teleport specified player to their last teleport location", arguments = "") + public void executeBackTeleportOther(@Sender Viewer viewer, @Arg Player target) { + Optional> backPair = this.backService.getBackLocationPair(target.getUniqueId()); + + if (backPair.isEmpty() || backPair.get().getSecond() == null) { + this.noticeService.viewer(viewer, translation -> translation.back().lastLocationNoExist()); + return; + } + + BackLocation teleportLocation = backPair.get().getSecond(); + this.backService.teleportBack(target, teleportLocation.location()); + this.noticeService.player(target.getUniqueId(), translation -> translation.back().teleportedToLastLocation()); + + this.noticeService.create() + .viewer(viewer) + .notice(translation -> translation.back().teleportedSpecifiedPlayerLastLocation()) + .placeholder("{PLAYER}", target.getName()) + .send(); + } +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/BackController.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/BackController.java new file mode 100644 index 000000000..a3dc1e008 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/BackController.java @@ -0,0 +1,35 @@ +package com.eternalcode.core.feature.back; + +import com.eternalcode.core.injector.annotations.Inject; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerTeleportEvent; + +public class BackController implements Listener { + + private final BackService backService; + + @Inject + public BackController(BackService backService) { + this.backService = backService; + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerDeath(PlayerDeathEvent event) { + Player entity = event.getEntity(); + + this.backService.setBackLocation(entity.getUniqueId(), entity.getLocation(), true); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerTeleport(PlayerTeleportEvent event) { + if (event.getCause() == PlayerTeleportEvent.TeleportCause.PLUGIN) { + return; + } + + this.backService.setBackLocation(event.getPlayer().getUniqueId(), event.getFrom(), false); + } +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/BackService.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/BackService.java new file mode 100644 index 000000000..6c0b29999 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/BackService.java @@ -0,0 +1,79 @@ +package com.eternalcode.core.feature.back; + +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.injector.annotations.component.Service; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import panda.std.Pair; + +@Service +public class BackService { + + private final TeleportService teleportService; + private final TeleportTaskService teleportTaskService; + private final TeleportRequestSettings settings; + + private final Cache> backLocationsCache; + + @Inject + public BackService( + TeleportService teleportService, + TeleportTaskService teleportTaskService, + TeleportRequestSettings settings + ) { + this.teleportService = teleportService; + this.teleportTaskService = teleportTaskService; + this.settings = settings; + + this.backLocationsCache = Caffeine.newBuilder() + .maximumSize(1000) + .expireAfterWrite(2, TimeUnit.HOURS) + .build(); + } + + public Optional> getBackLocationPair(UUID playerId) { + return Optional.ofNullable(backLocationsCache.getIfPresent(playerId)); + } + + public void setBackLocation(UUID playerId, Location location, boolean isFromDeath) { + Pair existing = backLocationsCache.getIfPresent(playerId); + BackLocation newLocation = new BackLocation(location); + BackLocation deathLocation; + BackLocation normalLocation; + if (existing == null) { + deathLocation = isFromDeath ? newLocation : null; + normalLocation = isFromDeath ? null : newLocation; + } + else { + deathLocation = isFromDeath ? newLocation : existing.getFirst(); + normalLocation = isFromDeath ? existing.getSecond() : newLocation; + } + backLocationsCache.put(playerId, Pair.of(deathLocation, normalLocation)); + } + + public void teleportBack(Player player, Location location) { + if (player.hasPermission("eternalcore.teleport.bypass")) { + teleportService.teleport(player, location); + } + else { + teleportTaskService.createTeleport( + player.getUniqueId(), + PositionAdapter.convert(player.getLocation()), + PositionAdapter.convert(location), + settings.tpaTimer() + ); + } + } + + public record BackLocation(Location location) { + } +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/messages/BackMessages.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/messages/BackMessages.java new file mode 100644 index 000000000..5b0fecff3 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/messages/BackMessages.java @@ -0,0 +1,13 @@ +package com.eternalcode.core.feature.back.messages; + +import com.eternalcode.multification.notice.Notice; + +public interface BackMessages { + + Notice lastLocationNoExist(); + + Notice teleportedToLastLocation(); + + Notice teleportedSpecifiedPlayerLastLocation(); + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/messages/ENBackMessages.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/messages/ENBackMessages.java new file mode 100644 index 000000000..685ce339e --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/messages/ENBackMessages.java @@ -0,0 +1,16 @@ +package com.eternalcode.core.feature.back.messages; + +import com.eternalcode.multification.notice.Notice; +import eu.okaeri.configs.OkaeriConfig; +import lombok.Getter; +import lombok.experimental.Accessors; + +@Getter +@Accessors(fluent = true) +public class ENBackMessages extends OkaeriConfig implements BackMessages { + + public Notice lastLocationNoExist = Notice.chat("You don't have any last location to teleport to!"); + public Notice teleportedToLastLocation = Notice.chat("You have been teleported to your last location!"); + public Notice teleportedSpecifiedPlayerLastLocation = Notice.chat("Player {PLAYER} has been teleported to their last location!"); + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/messages/PLBackMessages.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/messages/PLBackMessages.java new file mode 100644 index 000000000..275dc1e0c --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/back/messages/PLBackMessages.java @@ -0,0 +1,16 @@ +package com.eternalcode.core.feature.back.messages; + +import com.eternalcode.multification.notice.Notice; +import eu.okaeri.configs.OkaeriConfig; +import lombok.Getter; +import lombok.experimental.Accessors; + +@Getter +@Accessors(fluent = true) +public class PLBackMessages extends OkaeriConfig implements BackMessages { + + public Notice lastLocationNoExist = Notice.chat("Nie masz żadnej ostatniej lokalizacji, do której można się teleportować!"); + public Notice teleportedToLastLocation = Notice.chat("Zostałeś przeteleportowany do ostatniej lokalizacji!"); + public Notice teleportedSpecifiedPlayerLastLocation = Notice.chat("Gracz {PLAYER} został przeteleportowany do swojej ostatniej lokalizacji!"); + +} 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 deleted file mode 100644 index 078bb8bc4..000000000 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/teleport/command/TeleportBackCommand.java +++ /dev/null @@ -1,84 +0,0 @@ -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.viewer.Viewer; -import dev.rollczi.litecommands.annotations.argument.Arg; -import dev.rollczi.litecommands.annotations.command.Command; -import dev.rollczi.litecommands.annotations.context.Sender; -import dev.rollczi.litecommands.annotations.execute.Execute; -import dev.rollczi.litecommands.annotations.permission.Permission; -import java.util.Optional; -import org.bukkit.Location; -import org.bukkit.entity.Player; - -@Command(name = "back") -class TeleportBackCommand { - - private final TeleportService teleportService; - private final TeleportTaskService teleportTaskService; - private final TeleportRequestSettings settings; - private final NoticeService noticeService; - - @Inject - TeleportBackCommand(TeleportService teleportService, TeleportTaskService teleportTaskService, TeleportRequestSettings settings, NoticeService noticeService) { - this.teleportService = teleportService; - this.teleportTaskService = teleportTaskService; - this.settings = settings; - this.noticeService = noticeService; - } - - @Execute - @Permission("eternalcore.back") - @DescriptionDocs(description = "Teleport to last location") - void execute(@Sender Player player) { - Optional location = this.teleportService.getLastLocation(player.getUniqueId()); - - if (location.isEmpty()) { - this.noticeService.player(player.getUniqueId(), translation -> translation.teleport().lastLocationNoExist()); - - return; - } - - 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.tpaTimer()); - } - - this.noticeService.player(player.getUniqueId(), translation -> translation.teleport().teleportedToLastLocation()); - } - - @Execute - @Permission("eternalcore.back.other") - @DescriptionDocs(description = "Teleport specified player to last location", arguments = "") - void execute(@Sender Viewer viewer, @Arg Player player) { - Optional location = this.teleportService.getLastLocation(player.getUniqueId()); - - if (location.isEmpty()) { - this.noticeService.viewer(viewer, translation -> translation.teleport().lastLocationNoExist()); - - return; - } - - 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.tpaTimer()); - } - - this.noticeService.player(player.getUniqueId(), translation -> translation.teleport().teleportedToLastLocation()); - - this.noticeService.create() - .viewer(viewer) - .notice(translation -> translation.teleport().teleportedSpecifiedPlayerLastLocation()) - .placeholder("{PLAYER}", player.getName()) - .send(); - } - -} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/translation/Translation.java b/eternalcore-core/src/main/java/com/eternalcode/core/translation/Translation.java index 9fd383c8a..c63af7bbb 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/translation/Translation.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/translation/Translation.java @@ -1,5 +1,12 @@ package com.eternalcode.core.translation; +import com.eternalcode.core.feature.back.messages.BackMessages; +import com.eternalcode.core.feature.freeze.messages.FreezeMessages; +import com.eternalcode.core.feature.playtime.messages.PlaytimeMessages; +import com.eternalcode.core.feature.clear.messages.ClearMessages; +import com.eternalcode.core.feature.container.messages.ContainerMessages; +import com.eternalcode.core.feature.repair.messages.RepairMessages; +import com.eternalcode.core.litecommand.argument.messages.ArgumentMessages; import com.eternalcode.core.feature.adminchat.messages.AdminChatMessages; import com.eternalcode.core.feature.afk.messages.AfkMessages; import com.eternalcode.core.feature.automessage.messages.AutoMessageMessages; @@ -65,11 +72,6 @@ interface TeleportSection { // Coordinates XYZ Notice teleportedToCoordinates(); Notice teleportedSpecifiedPlayerToCoordinates(); - - // Back - Notice teleportedToLastLocation(); - Notice teleportedSpecifiedPlayerLastLocation(); - Notice lastLocationNoExist(); } interface ChatSection { @@ -197,6 +199,7 @@ interface ItemSection { SudoMessages sudo(); // Teleport Section TeleportSection teleport(); + BackMessages back(); // teleport to random player section. TeleportToRandomPlayerMessages teleportToRandomPlayer(); // Random Teleport Section diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/ENTranslation.java b/eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/ENTranslation.java index 3a0483f3e..f7324736f 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/ENTranslation.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/ENTranslation.java @@ -1,9 +1,6 @@ package com.eternalcode.core.translation.implementation; -import com.eternalcode.core.feature.butcher.messages.ButcherMessages; -import com.eternalcode.core.feature.butcher.messages.ENButcherMessages; -import com.eternalcode.core.feature.enchant.messages.ENEnchantMessages; -import com.eternalcode.core.feature.enchant.messages.EnchantMessages; +import com.eternalcode.core.feature.back.messages.ENBackMessages; import com.eternalcode.core.feature.freeze.messages.ENFreezeMessages; import com.eternalcode.core.feature.playtime.messages.ENPlaytimeMessages; import com.eternalcode.core.feature.clear.messages.ENClearMessages; @@ -221,16 +218,14 @@ public static class ENTeleportSection extends OkaeriConfig implements TeleportSe public Notice teleportedToCoordinates = Notice.chat("Teleported to location x: {X}, y: {Y}, z: {Z}"); @Comment({" ", "# {PLAYER} - Player who has been teleported, {X} - X coordinate, {Y} - Y coordinate, {Z} - Z coordinate"}) public Notice teleportedSpecifiedPlayerToCoordinates = Notice.chat("Teleported {PLAYER} to location x: {X}, y: {Y}, z: {Z}"); - - // Back - @Comment(" ") - public Notice teleportedToLastLocation = Notice.chat("Teleported to the last location!"); - @Comment({" ", "# {PLAYER} - Player who has been teleported"}) - public Notice teleportedSpecifiedPlayerLastLocation = Notice.chat("Teleported {PLAYER} to the last location!"); - @Comment(" ") - public Notice lastLocationNoExist = Notice.chat("Last location is not exist!"); } + @Comment({ + " ", + "# This section is responsible for the messages of the /back command", + }) + public ENBackMessages back = new ENBackMessages(); + @Comment({ " ", "# This section is responsible for the messages of the /tprp command", diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/PLTranslation.java b/eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/PLTranslation.java index 1bcbe2a49..93c44d681 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/PLTranslation.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/PLTranslation.java @@ -1,10 +1,6 @@ package com.eternalcode.core.translation.implementation; -import com.eternalcode.core.feature.butcher.messages.ButcherMessages; -import com.eternalcode.core.feature.butcher.messages.ENButcherMessages; -import com.eternalcode.core.feature.enchant.messages.ENEnchantMessages; -import com.eternalcode.core.feature.enchant.messages.EnchantMessages; -import com.eternalcode.core.feature.enchant.messages.PLEnchantMessages; +import com.eternalcode.core.feature.back.messages.PLBackMessages; import com.eternalcode.core.feature.freeze.messages.PLFreezeMessages; import com.eternalcode.core.feature.near.messages.PLNearMessages; import com.eternalcode.core.feature.playtime.messages.PLPlaytimeMessages; @@ -249,6 +245,12 @@ public static class PLTeleportSection extends OkaeriConfig implements TeleportSe public Notice lastLocationNoExist = Notice.chat("Nie ma zapisanej ostatniej lokalizacji!"); } + @Comment({ + " ", + "# Ta sekcja odpowiada za wiadomości komendy /back" + }) + public PLBackMessages back = new PLBackMessages(); + @Comment({ " ", "# Ta sekcja odpowiada za wiadomości komendy /tprp"