Skip to content

Commit 5a48403

Browse files
authored
GH-1075 Add /tprp for caves. Move tprp feature to own section. (#1077)
* Add /tprp for caves. * Fix. * Remove useless migration. * Follow mike's feedback.
1 parent f09949c commit 5a48403

File tree

10 files changed

+193
-31
lines changed

10 files changed

+193
-31
lines changed

eternalcore-core/src/main/java/com/eternalcode/core/configuration/ConfigurationManager.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ public <T extends OkaeriConfig & EternalConfigurationFile> T load(T config) {
6565
.withSerdesPack(serdesPack)
6666
.withBindFile(file)
6767
.saveDefaults()
68+
.withRemoveOrphans(true)
6869
.load(true)
6970
.migrate(Migrations.ALL); // Remember: migration should be launched after the #load method.
7071

eternalcore-core/src/main/java/com/eternalcode/core/configuration/migrations/Migration_0003_Move_tprp_to_dedicated_section.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ class Migration_0003_Move_tprp_to_dedicated_section extends NamedMigration {
99
Migration_0003_Move_tprp_to_dedicated_section() {
1010
super(
1111
"Move tprp to dedicated config section",
12-
move("teleport", "teleportToRandomPlayer"),
13-
move(
14-
"teleportToRandomPlayer.includeOpPlayersInRandomTeleport",
15-
"teleportToRandomPlayer.teleportToOpPlayers")
12+
move("teleport.includeOpPlayersInRandomTeleport", "teleportToRandomPlayer.teleportToOpPlayers"),
13+
14+
// for translation files
15+
move("teleport.randomPlayerNotFound", "teleportToRandomPlayer.randomPlayerNotFound"),
16+
move("teleport.teleportedToRandomPlayer", "teleportToRandomPlayer.teleportedToRandomPlayer")
1617
);
1718
}
1819
}

eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrandomplayer/TeleportRandomPlayerService.java

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
import com.eternalcode.core.injector.annotations.component.Service;
55
import com.github.benmanes.caffeine.cache.Cache;
66
import com.github.benmanes.caffeine.cache.Caffeine;
7-
import java.time.Instant;
8-
import java.util.Comparator;
9-
import java.util.UUID;
107
import java.util.concurrent.TimeUnit;
118
import org.bukkit.Server;
129
import org.bukkit.entity.Player;
10+
11+
import java.time.Instant;
12+
import java.util.Comparator;
13+
import java.util.UUID;
14+
import java.util.List;
15+
import java.util.stream.Collectors;
1316
import org.jetbrains.annotations.Nullable;
1417

1518
@Service
@@ -34,21 +37,83 @@ public TeleportRandomPlayerService(
3437
@Nullable
3538
public Player findLeastRecentlyTeleportedPlayer(Player sender) {
3639
UUID senderId = sender.getUniqueId();
37-
return this.server.getOnlinePlayers().stream()
40+
41+
List<Player> validTargets = this.server.getOnlinePlayers().stream()
3842
.filter(target -> !target.equals(sender))
3943
.filter(target -> this.randomPlayerSettings.teleportToOpPlayers() || !target.isOp())
44+
.collect(Collectors.toList());
45+
46+
if (validTargets.isEmpty()) {
47+
return null;
48+
}
49+
50+
return validTargets.stream()
4051
.min(Comparator.comparing(target -> this.getTeleportationHistory(target, senderId)))
4152
.orElse(null);
4253
}
4354

55+
@Nullable
56+
public Player findLeastRecentlyTeleportedPlayerByY(Player sender, int minY, int maxY) {
57+
if (minY > maxY) {
58+
throw new IllegalArgumentException("MinY cannot be greater than maxY");
59+
}
60+
61+
UUID senderId = sender.getUniqueId();
62+
63+
List<Player> validTargets = this.server.getOnlinePlayers().stream()
64+
.filter(target -> !target.equals(sender))
65+
.filter(target -> this.randomPlayerSettings.teleportToOpPlayers() || !target.isOp())
66+
.filter(target -> this.isPlayerInYRange(target, minY, maxY))
67+
.collect(Collectors.toList());
68+
69+
if (validTargets.isEmpty()) {
70+
return null;
71+
}
72+
73+
return validTargets.stream()
74+
.min(Comparator.comparing(target -> this.getTeleportationHistory(target, senderId)))
75+
.orElse(null);
76+
}
77+
78+
private boolean isPlayerInYRange(Player player, int minY, int maxY) {
79+
if (player == null) {
80+
return false;
81+
}
82+
else {
83+
player.getLocation();
84+
}
85+
86+
double playerY = player.getLocation().getY();
87+
return playerY >= minY && playerY <= maxY;
88+
}
89+
4490
private Instant getTeleportationHistory(Player target, UUID senderId) {
45-
return this.teleportationHistory.get(new HistoryKey(senderId, target.getUniqueId()), key -> Instant.EPOCH);
91+
if (target == null) {
92+
return Instant.EPOCH;
93+
}
94+
95+
return this.teleportationHistory.get(
96+
new HistoryKey(senderId, target.getUniqueId()),
97+
key -> Instant.EPOCH
98+
);
4699
}
47100

48101
public void updateTeleportationHistory(Player sender, Player target) {
49-
this.teleportationHistory.put(new HistoryKey(sender.getUniqueId(), target.getUniqueId()), Instant.now());
102+
if (sender == null || target == null) {
103+
return;
104+
}
105+
106+
this.teleportationHistory.put(
107+
new HistoryKey(sender.getUniqueId(), target.getUniqueId()),
108+
Instant.now()
109+
);
50110
}
51111

52112
private record HistoryKey(UUID sender, UUID target) {
113+
public HistoryKey {
114+
if (sender == null || target == null) {
115+
throw new IllegalArgumentException("Sender and target UUIDs cannot be null");
116+
}
117+
}
53118
}
54119
}

eternalcore-core/src/main/java/com/eternalcode/core/feature/teleportrandomplayer/TeleportToRandomPlayerCommand.java

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.eternalcode.annotations.scan.command.DescriptionDocs;
44
import com.eternalcode.core.injector.annotations.Inject;
55
import com.eternalcode.core.notice.NoticeService;
6+
import dev.rollczi.litecommands.annotations.argument.Arg;
67
import dev.rollczi.litecommands.annotations.command.Command;
78
import dev.rollczi.litecommands.annotations.context.Context;
89
import dev.rollczi.litecommands.annotations.execute.Execute;
@@ -31,30 +32,58 @@ public TeleportToRandomPlayerCommand(
3132
void execute(@Context Player player) {
3233
Player targetPlayer = this.randomPlayerService.findLeastRecentlyTeleportedPlayer(player);
3334

34-
if (targetPlayer != null && targetPlayer.equals(player)) {
35+
if (targetPlayer == null || !targetPlayer.isOnline()) {
3536
this.noticeService.create()
3637
.player(player.getUniqueId())
37-
.notice(translation -> translation.teleport().randomPlayerNotFound())
38+
.notice(translation -> translation.teleportToRandomPlayer().randomPlayerNotFound())
3839
.send();
3940
return;
4041
}
4142

42-
if (targetPlayer == null) {
43+
this.randomPlayerService.updateTeleportationHistory(player, targetPlayer);
44+
PaperLib.teleportAsync(player, targetPlayer.getLocation());
45+
46+
this.noticeService.create()
47+
.player(player.getUniqueId())
48+
.notice(translation -> translation.teleportToRandomPlayer().teleportedToRandomPlayer())
49+
.placeholder("{PLAYER}", targetPlayer.getName())
50+
.send();
51+
}
52+
53+
/**
54+
* Teleports the player to a random player within a specific Y-level range.
55+
* Useful for finding players in caves, spotting potential x-rayers,
56+
* or quickly locating players in general.
57+
*/
58+
@Execute
59+
@DescriptionDocs(description = "Teleport to a player who is within specified Y range and hasn't been teleported to recently")
60+
void executeWithYRange(@Context Player player, @Arg int minY, @Arg int maxY) {
61+
if (minY > maxY) {
4362
this.noticeService.create()
4463
.player(player.getUniqueId())
45-
.notice(translation -> translation.teleport().randomPlayerNotFound())
64+
.notice(translation -> translation.teleportToRandomPlayer().randomPlayerInRangeNotFound())
4665
.send();
4766
return;
4867
}
4968

50-
this.randomPlayerService.updateTeleportationHistory(player, targetPlayer);
69+
Player targetPlayer = this.randomPlayerService.findLeastRecentlyTeleportedPlayerByY(player, minY, maxY);
5170

71+
if (targetPlayer == null || !targetPlayer.isOnline()) {
72+
this.noticeService.create()
73+
.player(player.getUniqueId())
74+
.notice(translation -> translation.teleportToRandomPlayer().randomPlayerInRangeNotFound())
75+
.send();
76+
return;
77+
}
78+
79+
this.randomPlayerService.updateTeleportationHistory(player, targetPlayer);
5280
PaperLib.teleportAsync(player, targetPlayer.getLocation());
5381

5482
this.noticeService.create()
5583
.player(player.getUniqueId())
56-
.notice(translation -> translation.teleport().teleportedToRandomPlayer())
84+
.notice(translation -> translation.teleportToRandomPlayer().teleportedToRandomPlayerInRange())
5785
.placeholder("{PLAYER}", targetPlayer.getName())
86+
.placeholder("{Y}", String.valueOf((int) targetPlayer.getLocation().getY()))
5887
.send();
5988
}
60-
}
89+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.eternalcode.core.feature.teleportrandomplayer.messages;
2+
3+
import com.eternalcode.multification.notice.Notice;
4+
import eu.okaeri.configs.OkaeriConfig;
5+
import eu.okaeri.configs.annotation.Comment;
6+
import lombok.Getter;
7+
import lombok.experimental.Accessors;
8+
9+
@Getter
10+
@Accessors(fluent = true)
11+
public class ENTeleportToRandomPlayerMessages extends OkaeriConfig implements TeleportToRandomPlayerMessages {
12+
13+
public Notice randomPlayerNotFound =
14+
Notice.chat("<red>✘ <dark_red>No player found to teleport!");
15+
16+
@Comment("{PLAYER} - The name of the player you have been teleported to")
17+
public Notice teleportedToRandomPlayer =
18+
Notice.chat("<green>► <white>Teleported to random player <green>{PLAYER}<white>!");
19+
20+
public Notice randomPlayerInRangeNotFound =
21+
Notice.chat("<red>✘ <dark_red>No player found in range to teleport!");
22+
23+
@Comment("{PLAYER} - The name of the player you have been teleported to within range")
24+
public Notice teleportedToRandomPlayerInRange =
25+
Notice.chat("<green>► <white>Teleported to a random player in range: <green>{PLAYER}<white>!");
26+
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.eternalcode.core.feature.teleportrandomplayer.messages;
2+
3+
import com.eternalcode.multification.notice.Notice;
4+
import eu.okaeri.configs.OkaeriConfig;
5+
import eu.okaeri.configs.annotation.Comment;
6+
import lombok.Getter;
7+
import lombok.experimental.Accessors;
8+
9+
@Getter
10+
@Accessors(fluent = true)
11+
public class PLTeleportToRandomPlayerMessages extends OkaeriConfig implements TeleportToRandomPlayerMessages {
12+
13+
public Notice randomPlayerNotFound =
14+
Notice.chat("<red>✘ <dark_red>Nie można odnaleźć gracza do teleportacji!");
15+
16+
@Comment("{PLAYER} - Nazwa gracza, do którego zostałeś teleportowany")
17+
public Notice teleportedToRandomPlayer =
18+
Notice.chat("<green>► <white>Zostałeś losowo teleportowany do <green>{PLAYER}<white>!");
19+
20+
public Notice randomPlayerInRangeNotFound =
21+
Notice.chat("<red>✘ <dark_red>Nie można odnaleźć gracza w zasięgu do teleportacji!");
22+
23+
@Comment("{PLAYER} - Nazwa gracza, do którego zostałeś teleportowany w zasięgu")
24+
public Notice teleportedToRandomPlayerInRange =
25+
Notice.chat("<green>► <white>Zostałeś losowo teleportowany do gracza w zasięgu: <green>{PLAYER}<white>!");
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.eternalcode.core.feature.teleportrandomplayer.messages;
2+
3+
import com.eternalcode.multification.notice.Notice;
4+
5+
public interface TeleportToRandomPlayerMessages {
6+
Notice randomPlayerNotFound();
7+
Notice teleportedToRandomPlayer();
8+
Notice randomPlayerInRangeNotFound();
9+
Notice teleportedToRandomPlayerInRange();
10+
}

eternalcore-core/src/main/java/com/eternalcode/core/translation/Translation.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.eternalcode.core.feature.signeditor.messages.SignEditorMessages;
2323
import com.eternalcode.core.feature.spawn.messages.SpawnMessages;
2424
import com.eternalcode.core.feature.sudo.messages.SudoMessages;
25+
import com.eternalcode.core.feature.teleportrandomplayer.messages.TeleportToRandomPlayerMessages;
2526
import com.eternalcode.core.feature.teleportrequest.messages.TeleportRequestMessages;
2627
import com.eternalcode.core.feature.time.messages.TimeAndWeatherMessages;
2728
import com.eternalcode.core.feature.vanish.messages.VanishMessages;
@@ -61,10 +62,6 @@ interface TeleportSection {
6162
Notice teleportedToLastLocation();
6263
Notice teleportedSpecifiedPlayerLastLocation();
6364
Notice lastLocationNoExist();
64-
65-
// teleport to random player command
66-
Notice randomPlayerNotFound();
67-
Notice teleportedToRandomPlayer();
6865
}
6966

7067
interface ChatSection {
@@ -206,6 +203,8 @@ interface ContainerSection {
206203
SudoMessages sudo();
207204
// Teleport Section
208205
TeleportSection teleport();
206+
// teleport to random player section.
207+
TeleportToRandomPlayerMessages teleportToRandomPlayer();
209208
// Random Teleport Section
210209
RandomTeleportMessages randomTeleport();
211210
// Chat Section

eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/ENTranslation.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.eternalcode.core.feature.signeditor.messages.ENSignEditorMessages;
2424
import com.eternalcode.core.feature.spawn.messages.ENSpawnMessages;
2525
import com.eternalcode.core.feature.sudo.messages.ENSudoMessages;
26+
import com.eternalcode.core.feature.teleportrandomplayer.messages.ENTeleportToRandomPlayerMessages;
2627
import com.eternalcode.core.feature.teleportrequest.messages.ENTeleportRequestMessages;
2728
import com.eternalcode.core.feature.time.messages.ENTimeAndWeatherMessages;
2829
import com.eternalcode.core.feature.vanish.messages.ENVanishMessages;
@@ -212,13 +213,14 @@ public static class ENTeleportSection extends OkaeriConfig implements TeleportSe
212213
public Notice teleportedSpecifiedPlayerLastLocation = Notice.chat("<green>► <white>Teleported <green>{PLAYER} <white>to the last location!");
213214
@Comment(" ")
214215
public Notice lastLocationNoExist = Notice.chat("<red>✘ <dark_red>Last location is not exist!");
215-
216-
@Comment(" ")
217-
public Notice randomPlayerNotFound = Notice.chat("<red>✘ <dark_red>No player found to teleport!");
218-
@Comment({" ", "# {PLAYER} - The player you were teleported"})
219-
public Notice teleportedToRandomPlayer = Notice.chat("<green>► <white>Teleported to random player <green>{PLAYER}<white>!");
220216
}
221217

218+
@Comment({
219+
" ",
220+
"# This section is responsible for the messages of the /tprp command",
221+
})
222+
public ENTeleportToRandomPlayerMessages teleportToRandomPlayer = new ENTeleportToRandomPlayerMessages();
223+
222224
@Comment({
223225
" ",
224226
"# This section is responsible for messages related to random teleport",

eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/PLTranslation.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.eternalcode.core.feature.signeditor.messages.PLSignEditorMessages;
2424
import com.eternalcode.core.feature.spawn.messages.PLSpawnMessages;
2525
import com.eternalcode.core.feature.sudo.messages.PLSudoMessages;
26+
import com.eternalcode.core.feature.teleportrandomplayer.messages.PLTeleportToRandomPlayerMessages;
2627
import com.eternalcode.core.feature.teleportrequest.messages.PLTeleportRequestMessages;
2728
import com.eternalcode.core.feature.time.messages.PLTimeAndWeatherMessages;
2829
import com.eternalcode.core.feature.vanish.messages.PLVanishMessages;
@@ -213,13 +214,14 @@ public static class PLTeleportSection extends OkaeriConfig implements TeleportSe
213214
public Notice teleportedSpecifiedPlayerLastLocation = Notice.chat("<green>► <white>Przeteleportowano gracza <green>{PLAYER} <white>do ostatniej lokalizacji!");
214215
@Comment(" ")
215216
public Notice lastLocationNoExist = Notice.chat("<red>✘ <dark_red>Nie ma zapisanej ostatniej lokalizacji!");
216-
217-
@Comment(" ")
218-
public Notice randomPlayerNotFound = Notice.chat("<red>✘ <dark_red>Nie można odnaleźć gracza do teleportacji!");
219-
@Comment({" ", "# {PLAYER} - Gracz do którego cię teleportowano"})
220-
public Notice teleportedToRandomPlayer = Notice.chat("<green>► <white>Zostałeś losowo teleportowany do <green>{PLAYER}<white>!");
221217
}
222218

219+
@Comment({
220+
" ",
221+
"# Ta sekcja odpowiada za wiadomości komendy /tprp"
222+
})
223+
public PLTeleportToRandomPlayerMessages teleportToRandomPlayer = new PLTeleportToRandomPlayerMessages();
224+
223225
@Comment({
224226
" ",
225227
"# Ta sekcja odpowiada za edycję komunikatów losowej teleportacji",

0 commit comments

Comments
 (0)