Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import com.eternalcode.core.feature.afk.AfkSettings;
import com.eternalcode.core.feature.automessage.AutoMessageConfig;
import com.eternalcode.core.feature.automessage.AutoMessageSettings;
import com.eternalcode.core.feature.back.BackConfig;
import com.eternalcode.core.feature.back.BackSettings;
import com.eternalcode.core.feature.broadcast.BroadcastConfig;
import com.eternalcode.core.feature.broadcast.BroadcastSettings;
import com.eternalcode.core.feature.butcher.ButcherConfig;
Expand Down Expand Up @@ -50,8 +52,6 @@
import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Comment;
import eu.okaeri.configs.annotation.Header;
import org.bukkit.Sound;

import java.io.File;

@Header({
Expand Down Expand Up @@ -213,6 +213,12 @@ public static class Format extends OkaeriConfig {
@Comment("# Settings responsible for player vanish functionality")
VanishConfig vanish = new VanishConfig();

@Bean(proxied = BackSettings.class)
@Comment("")
@Comment("# Back Configuration")
@Comment("# Settings for the /back command functionality")
BackConfig back = new BackConfig();

@Override
public File getConfigFile(File dataFolder) {
return new File(dataFolder, "config.yml");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.eternalcode.core.configuration.migrations;

import static eu.okaeri.configs.migrate.ConfigMigrationDsl.move;

import eu.okaeri.configs.migrate.builtin.NamedMigration;

public class Migration_0030_Move_back_to_dedicated_section extends NamedMigration {
Migration_0030_Move_back_to_dedicated_section() {
super(
"Move back to dedicated section",
move("teleport.teleportedToLastLocation", "back.teleportedToLastTeleportLocation"),
move("teleport.teleportedSpecifiedPlayerLastLocation", "back.teleportedTargetPlayerToLastTeleportLocation"),
move("teleport.lastLocationNoExist", "back.lastLocationNotFound")
);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class Migrations {
new Migration_0013_Move_enchant_messages_to_dedicated_section(),
new Migration_0014_Move_butcher_messages_to_dedicated_section(),
new Migration_0015_Move_ignore_messages_to_dedicated_section(),
new Migration_0030_Move_back_to_dedicated_section(),
new Migration_0031_Move_death_messages_to_dedicated_section(),
new Migration_0032_Move_join_quit_messages_to_dedicated_section(),
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package com.eternalcode.core.feature.back;

import com.eternalcode.annotations.scan.command.DescriptionDocs;
import com.eternalcode.commons.bukkit.position.Position;
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;

@Command(name = "back")
class BackCommand {

private final BackService backService;
private final NoticeService noticeService;

@Inject
public BackCommand(BackService backService, NoticeService noticeService) {
this.backService = backService;
this.noticeService = noticeService;
}


@Execute
@Permission("eternalcore.back")
@DescriptionDocs(description = "Teleport to your last teleport/death location, depending which one is most recent")
public void executeBack(@Sender Player player) {
Optional<Position> latestPositionOptional = this.backService.getLatestLocation(player.getUniqueId());
if (latestPositionOptional.isEmpty()) {
this.noticeService.player(player.getUniqueId(), translation -> translation.back().lastLocationNotFound());
return;
}
Position latestPosition = latestPositionOptional.get();
Position deathPosition = this.backService.getDeathLocation(player.getUniqueId()).orElse(null);

if (latestPosition.equals(deathPosition)) {
this.executeBackDeath(player);
return;
}
this.executeBackTeleport(player);
}


@Execute(name = "teleport")
@Permission("eternalcore.back.teleport")
@DescriptionDocs(description = "Teleport to your last teleport location")
public void executeBackTeleport(@Sender Player player) {
if (this.backService.teleportBack(player)) {
this.noticeService.player(player.getUniqueId(), translation -> translation.back().teleportedToLastTeleportLocation());
return;
}
this.noticeService.player(player.getUniqueId(), translation -> translation.back().lastLocationNotFound());
}

@Execute(name = "death")
@Permission("eternalcore.back.death")
@DescriptionDocs(description = "Teleport to your last death location")
public void executeBackDeath(@Sender Player player) {
if (this.backService.teleportBackDeath(player)) {
this.noticeService.player(player.getUniqueId(), translation -> translation.back().teleportedToLastDeathLocation());
return;
}
this.noticeService.player(player.getUniqueId(), translation -> translation.back().lastLocationNotFound());
}

@Execute(name = "teleport")
@Permission("eternalcore.back.teleport.other")
@DescriptionDocs(description = "Teleport specified player to their last teleport location", arguments = "<player>")
public void executeBackTeleportOther(@Sender Viewer viewer, @Arg Player target) {
if (!this.backService.teleportBack(target)) {
this.noticeService.player(viewer.getUniqueId(), translation -> translation.back().lastLocationNotFound());
return;
}

this.noticeService.player(target.getUniqueId(), translation -> translation.back().teleportedToLastTeleportLocationByAdmin());
this.noticeService.create()
.viewer(viewer)
.notice(translation -> translation.back().teleportedTargetPlayerToLastTeleportLocation())
.placeholder("{PLAYER}", target.getName())
.send();
}

@Execute(name = "death")
@Permission("eternalcore.back.death.other")
@DescriptionDocs(description = "Teleport specified player to their last death location", arguments = "<player>")
public void executeBackDeathOther(@Sender Viewer viewer, @Arg Player target) {
if (!this.backService.teleportBackDeath(target)) {
this.noticeService.player(viewer.getUniqueId(), translation -> translation.back().lastLocationNotFound());
return;
}

this.noticeService.player(target.getUniqueId(), translation -> translation.back().teleportedToLastDeathLocationByAdmin());
this.noticeService.create()
.viewer(viewer)
.notice(translation -> translation.back().teleportedTargetPlayerToLastDeathLocation())
.placeholder("{PLAYER}", target.getName())
.send();

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.eternalcode.core.feature.back;

import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Comment;
import java.time.Duration;
import lombok.Getter;
import lombok.experimental.Accessors;

@Getter
@Accessors(fluent = true)
public class BackConfig extends OkaeriConfig implements BackSettings {

@Comment("# Time of teleportation time in /back command.")
public Duration backTeleportTimer = Duration.ofSeconds(5);

@Comment("# Duration of caching last locations for /back command.")
public Duration backLocationCacheDuration = Duration.ofHours(1);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.eternalcode.core.feature.back;

import com.eternalcode.commons.bukkit.position.PositionAdapter;
import com.eternalcode.core.injector.annotations.Inject;
import com.eternalcode.core.injector.annotations.component.Controller;
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;

@Controller
class BackController implements Listener {

private final BackService backService;

@Inject
BackController(BackService backService) {
this.backService = backService;
}

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerDeath(PlayerDeathEvent event) {
Player entity = event.getEntity();

this.backService.markDeathLocation(entity.getUniqueId(), PositionAdapter.convert(entity.getLocation()));
}

@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerTeleport(PlayerTeleportEvent event) {
if (event.getCause() == PlayerTeleportEvent.TeleportCause.PLUGIN) {
return;
}

this.backService.markTeleportLocation(event.getPlayer().getUniqueId(), PositionAdapter.convert(event.getFrom()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.eternalcode.core.feature.back;

import com.eternalcode.commons.bukkit.position.Position;
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.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 org.bukkit.Location;
import org.bukkit.entity.Player;

@Service
class BackService {

private static final String BYPASS_PERMISSION = "eternalcore.teleport.bypass";

private final TeleportService teleportService;
private final TeleportTaskService teleportTaskService;
private final BackSettings settings;

private final Cache<UUID, Position> deathLocations;
private final Cache<UUID, Position> teleportLocations;
private final Cache<UUID, Position> latestLocations;

@Inject
BackService(
TeleportService teleportService,
TeleportTaskService teleportTaskService,
BackSettings settings
) {
this.teleportService = teleportService;
this.teleportTaskService = teleportTaskService;
this.settings = settings;

this.deathLocations = Caffeine.newBuilder()
.expireAfterWrite(settings.backLocationCacheDuration())
.build();
this.teleportLocations = Caffeine.newBuilder()
.expireAfterWrite(settings.backLocationCacheDuration())
.build();
this.latestLocations = Caffeine.newBuilder()
.expireAfterWrite(settings.backLocationCacheDuration())
.build();
}

public Optional<Position> getDeathLocation(UUID playerId) {
return Optional.ofNullable(deathLocations.getIfPresent(playerId));
}

public Optional<Position> getTeleportLocation(UUID playerId) {
return Optional.ofNullable(teleportLocations.getIfPresent(playerId));
}

public Optional<Position> getLatestLocation(UUID playerId) {
return Optional.ofNullable(latestLocations.getIfPresent(playerId));
}

public void markDeathLocation(UUID player, Position position) {
this.deathLocations.put(player, position);
this.latestLocations.put(player, position);
}

public void markTeleportLocation(UUID player, Position position) {
this.teleportLocations.put(player, position);
this.latestLocations.put(player, position);
}

public boolean teleportBack(Player target) {
Optional<Position> teleportLocation = this.getTeleportLocation(target.getUniqueId());

if (teleportLocation.isPresent()) {
this.teleportBack(target, PositionAdapter.convert(teleportLocation.get()));

return true;
}
return false;
}

public boolean teleportBackDeath(Player target) {
Optional<Position> deathLocation = this.getDeathLocation(target.getUniqueId());

if (deathLocation.isPresent()) {
this.teleportBack(target, PositionAdapter.convert(deathLocation.get()));

return true;
}
return false;
}

private void teleportBack(Player player, Location location) {
if (player.hasPermission(BYPASS_PERMISSION)) {
teleportService.teleport(player, location);
return;
}
teleportTaskService.createTeleport(
player.getUniqueId(),
PositionAdapter.convert(player.getLocation()),
PositionAdapter.convert(location),
settings.backTeleportTimer()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.eternalcode.core.feature.back;

import java.time.Duration;

public interface BackSettings {

Duration backTeleportTimer();

Duration backLocationCacheDuration();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.eternalcode.core.feature.back.messages;

import com.eternalcode.multification.notice.Notice;

public interface BackMessages {

Notice lastLocationNotFound();

Notice teleportedToLastTeleportLocation();
Notice teleportedTargetPlayerToLastTeleportLocation();
Notice teleportedToLastTeleportLocationByAdmin();

Notice teleportedToLastDeathLocation();
Notice teleportedTargetPlayerToLastDeathLocation();
Notice teleportedToLastDeathLocationByAdmin();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
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 lastLocationNotFound = Notice.chat(
"<red>► <white>You don't have any last location to teleport to!");

public Notice teleportedToLastTeleportLocation = Notice.chat(
"<green>► <white>You have been teleported to your last location!");
public Notice teleportedTargetPlayerToLastTeleportLocation = Notice.chat(
"<green>► <white>Player <green>{PLAYER} <white>has been teleported to their last location!");
public Notice teleportedToLastTeleportLocationByAdmin = Notice.chat(
"<green>► <white>You have been teleported to your last location by an administrator!");

public Notice teleportedToLastDeathLocation = Notice.chat(
"<green>► <white>You have been teleported to your last death location!");
public Notice teleportedTargetPlayerToLastDeathLocation = Notice.chat(
"<green>► <white>Player <green>{PLAYER} <white>has been teleported to their last death location!");
public Notice teleportedToLastDeathLocationByAdmin = Notice.chat(
"<green>► <white>You have been teleported to your last death location by an administrator!");
}
Loading