Skip to content

Commit 47a44b7

Browse files
vLuckyyyRollczi
andauthored
GH-939 Fix /tprp command often teleports to the same player repeatedly (#941)
* GH-939 Fix `/tprp` command often teleports to the same player repeatedly * Code review * Code review * Follow review. * Fix --------- Co-authored-by: Rollczi <[email protected]>
1 parent 3726303 commit 47a44b7

File tree

3 files changed

+113
-63
lines changed

3 files changed

+113
-63
lines changed

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

Lines changed: 0 additions & 63 deletions
This file was deleted.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.eternalcode.core.feature.teleportrandomplayer;
2+
3+
import com.eternalcode.core.configuration.implementation.PluginConfiguration;
4+
import com.eternalcode.core.injector.annotations.Inject;
5+
import com.eternalcode.core.injector.annotations.component.Service;
6+
import com.github.benmanes.caffeine.cache.Cache;
7+
import com.github.benmanes.caffeine.cache.Caffeine;
8+
import java.util.concurrent.TimeUnit;
9+
import org.bukkit.Server;
10+
import org.bukkit.entity.Player;
11+
12+
import java.time.Instant;
13+
import java.util.Comparator;
14+
import java.util.UUID;
15+
import org.jetbrains.annotations.Nullable;
16+
17+
@Service
18+
public class TeleportRandomPlayerService {
19+
20+
private final Server server;
21+
private final PluginConfiguration pluginConfiguration;
22+
23+
private final Cache<HistoryKey, Instant> teleportationHistory = Caffeine.newBuilder()
24+
.expireAfterWrite(30, TimeUnit.MINUTES)
25+
.build();
26+
27+
@Inject
28+
public TeleportRandomPlayerService(Server server, PluginConfiguration pluginConfiguration) {
29+
this.server = server;
30+
this.pluginConfiguration = pluginConfiguration;
31+
}
32+
33+
@Nullable
34+
public Player findLeastRecentlyTeleportedPlayer(Player sender) {
35+
UUID senderId = sender.getUniqueId();
36+
return this.server.getOnlinePlayers().stream()
37+
.filter(target -> !target.equals(sender))
38+
.filter(target -> this.pluginConfiguration.teleport.includeOpPlayersInRandomTeleport || !target.isOp())
39+
.min(Comparator.comparing(target -> this.getTeleportationHistory(target, senderId)))
40+
.orElse(null);
41+
}
42+
43+
private Instant getTeleportationHistory(Player target, UUID senderId) {
44+
return this.teleportationHistory.get(new HistoryKey(senderId, target.getUniqueId()), key -> Instant.EPOCH);
45+
}
46+
47+
public void updateTeleportationHistory(Player sender, Player target) {
48+
this.teleportationHistory.put(new HistoryKey(sender.getUniqueId(), target.getUniqueId()), Instant.now());
49+
}
50+
51+
private record HistoryKey(UUID sender, UUID target) {
52+
}
53+
54+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.eternalcode.core.feature.teleportrandomplayer;
2+
3+
import com.eternalcode.annotations.scan.command.DescriptionDocs;
4+
import com.eternalcode.core.injector.annotations.Inject;
5+
import com.eternalcode.core.notice.NoticeService;
6+
import dev.rollczi.litecommands.annotations.command.Command;
7+
import dev.rollczi.litecommands.annotations.context.Context;
8+
import dev.rollczi.litecommands.annotations.execute.Execute;
9+
import dev.rollczi.litecommands.annotations.permission.Permission;
10+
import org.bukkit.entity.Player;
11+
12+
@Command(name = "teleportorandomplayer", aliases = {"tprp"})
13+
@Permission("eternalcode.tprp")
14+
public class TeleportToRandomPlayerCommand {
15+
16+
private final TeleportRandomPlayerService teleportRandomPlayerService;
17+
private final NoticeService noticeService;
18+
19+
@Inject
20+
public TeleportToRandomPlayerCommand(
21+
TeleportRandomPlayerService teleportRandomPlayerService,
22+
NoticeService noticeService
23+
) {
24+
this.teleportRandomPlayerService = teleportRandomPlayerService;
25+
this.noticeService = noticeService;
26+
}
27+
28+
@Execute
29+
@DescriptionDocs(description = "Teleport to a player who hasn't been teleported to recently, ensuring fair distribution")
30+
void execute(@Context Player player) {
31+
Player targetPlayer = this.teleportRandomPlayerService.findLeastRecentlyTeleportedPlayer(player);
32+
33+
if (targetPlayer != null && targetPlayer.equals(player)) {
34+
this.noticeService.create()
35+
.player(player.getUniqueId())
36+
.notice(translation -> translation.teleport().randomPlayerNotFound())
37+
.send();
38+
return;
39+
}
40+
41+
if (targetPlayer == null) {
42+
this.noticeService.create()
43+
.player(player.getUniqueId())
44+
.notice(translation -> translation.teleport().randomPlayerNotFound())
45+
.send();
46+
return;
47+
}
48+
49+
this.teleportRandomPlayerService.updateTeleportationHistory(targetPlayer, player);
50+
51+
player.teleport(targetPlayer);
52+
53+
this.noticeService.create()
54+
.player(player.getUniqueId())
55+
.notice(translation -> translation.teleport().teleportedToRandomPlayer())
56+
.placeholder("{PLAYER}", targetPlayer.getName())
57+
.send();
58+
}
59+
}

0 commit comments

Comments
 (0)