Skip to content

Commit 4164b51

Browse files
authored
Merge pull request #228 from GumMC/feature/multi-tpa-accept-deny
Implement queue for teleport requests
2 parents 0f70ef9 + cfc5f0e commit 4164b51

5 files changed

Lines changed: 245 additions & 27 deletions

File tree

API/src/main/java/fr/maxlego08/essentials/api/messages/Message.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ public enum Message {
140140
COMMAND_TELEPORT_WORLD("<error>You need to be in the same world to teleport."),
141141
COMMAND_TPA_ERROR_TO_LATE("<error>You do not have a teleport request."),
142142
COMMAND_TPA_ERROR_TO_LATE_2("<error>The request has expired."),
143+
COMMAND_TPA_ERROR_NO_REQUEST_FROM_PLAYER("<error>You do not have a teleport request from &f%player%<error>."),
144+
COMMAND_TPA_ACCEPT_ALL_SUCCESS("<success>You have accepted &f%count% <success>teleport request(s)."),
145+
COMMAND_TPA_DENY_ALL_SUCCESS("<success>You have denied &f%count% <success>teleport request(s)."),
143146
COMMAND_TP_DENY_SENDER("Denied %player% teleport request."),
144147
COMMAND_TP_DENY_RECEIVER("%player% has denied your teleport request"),
145148
COMMAND_TP_CANCEL_ERROR("<error>You did not send a teleport request at &f%player%<error>."),

API/src/main/java/fr/maxlego08/essentials/api/user/User.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,35 @@ public interface User {
135135
*/
136136
void removeTeleportRequest(User user);
137137

138+
/**
139+
* Gets teleport request from specific player.
140+
*
141+
* @param fromUser The player who sent the request
142+
* @return The request from specified player, or null if none exists
143+
*/
144+
TeleportRequest getTeleportRequestFrom(User fromUser);
145+
146+
/**
147+
* Gets all incoming teleport requests.
148+
*
149+
* @return Collection of all valid incoming requests
150+
*/
151+
Collection<TeleportRequest> getIncomingTeleportRequests();
152+
153+
/**
154+
* Adds or updates incoming teleport request.
155+
*
156+
* @param teleportRequest The request to add/update
157+
*/
158+
void setIncomingTeleportRequest(TeleportRequest teleportRequest);
159+
160+
/**
161+
* Removes incoming request from specific player.
162+
*
163+
* @param fromUser The player whose request should be removed
164+
*/
165+
void removeIncomingTeleportRequest(User fromUser);
166+
138167
/**
139168
* Teleports the user to the specified location immediately.
140169
*

src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportAccept.java

Lines changed: 82 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@
55
import fr.maxlego08.essentials.api.commands.Permission;
66
import fr.maxlego08.essentials.api.messages.Message;
77
import fr.maxlego08.essentials.api.user.TeleportRequest;
8+
import fr.maxlego08.essentials.api.user.User;
89
import fr.maxlego08.essentials.module.modules.TeleportationModule;
910
import fr.maxlego08.essentials.zutils.utils.commands.VCommand;
11+
import org.bukkit.OfflinePlayer;
12+
import org.bukkit.entity.Player;
13+
14+
import java.util.ArrayList;
15+
import java.util.Collection;
1016

1117
public class CommandTeleportAccept extends VCommand {
1218

@@ -15,26 +21,90 @@ public CommandTeleportAccept(EssentialsPlugin plugin) {
1521
this.setModule(TeleportationModule.class);
1622
this.setPermission(Permission.ESSENTIALS_TPA_ACCEPT);
1723
this.setDescription(Message.DESCRIPTION_TPA_ACCEPT);
24+
this.addOptionalArg("player");
1825
this.onlyPlayers();
1926
}
2027

2128
@Override
2229
protected CommandResultType perform(EssentialsPlugin plugin) {
2330

24-
TeleportRequest teleportRequest = this.user.getTeleportRequest();
25-
if (teleportRequest == null) {
26-
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE);
27-
return CommandResultType.DEFAULT;
28-
}
31+
String arg = this.argAsString(0, null);
2932

30-
if (!teleportRequest.isValid()) {
31-
this.user.setTeleportRequest(null);
32-
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE_2);
33-
return CommandResultType.DEFAULT;
34-
}
33+
if (arg == null) {
34+
// accept latest request
35+
TeleportRequest teleportRequest = this.user.getTeleportRequest();
36+
if (teleportRequest == null) {
37+
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE);
38+
return CommandResultType.DEFAULT;
39+
}
40+
41+
if (!teleportRequest.isValid()) {
42+
this.user.removeIncomingTeleportRequest(teleportRequest.getFromUser());
43+
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE_2);
44+
return CommandResultType.DEFAULT;
45+
}
46+
47+
teleportRequest.accept();
48+
this.user.removeIncomingTeleportRequest(teleportRequest.getFromUser());
49+
50+
} else if (arg.equals("*")) {
51+
// accept all pending requests
52+
Collection<TeleportRequest> requests = this.user.getIncomingTeleportRequests();
53+
if (requests.isEmpty()) {
54+
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE);
55+
return CommandResultType.DEFAULT;
56+
}
57+
58+
int count = 0;
59+
for (TeleportRequest request : new ArrayList<>(requests)) {
60+
if (request.isValid()) {
61+
request.accept();
62+
this.user.removeIncomingTeleportRequest(request.getFromUser());
63+
count++;
64+
}
65+
}
3566

36-
teleportRequest.accept();
37-
this.user.setTeleportRequest(null);
67+
if (count > 0) {
68+
message(sender, Message.COMMAND_TPA_ACCEPT_ALL_SUCCESS, "%count%", count);
69+
} else {
70+
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE);
71+
return CommandResultType.DEFAULT;
72+
}
73+
74+
} else {
75+
// accept request from that player
76+
Player targetPlayer = this.argAsPlayer(0);
77+
User targetUser = null;
78+
79+
if (targetPlayer != null) {
80+
targetUser = plugin.getStorageManager().getStorage().getUser(targetPlayer.getUniqueId());
81+
} else {
82+
OfflinePlayer offlinePlayer = this.argAsOfflinePlayer(0);
83+
if (offlinePlayer != null && offlinePlayer.hasPlayedBefore()) {
84+
targetUser = plugin.getStorageManager().getStorage().getUser(offlinePlayer.getUniqueId());
85+
}
86+
}
87+
88+
if (targetUser == null) {
89+
message(sender, Message.PLAYER_NOT_FOUND, "%player%", arg);
90+
return CommandResultType.DEFAULT;
91+
}
92+
93+
TeleportRequest teleportRequest = this.user.getTeleportRequestFrom(targetUser);
94+
if (teleportRequest == null) {
95+
message(sender, Message.COMMAND_TPA_ERROR_NO_REQUEST_FROM_PLAYER, "%player%", targetUser.getName());
96+
return CommandResultType.DEFAULT;
97+
}
98+
99+
if (!teleportRequest.isValid()) {
100+
this.user.removeIncomingTeleportRequest(targetUser);
101+
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE_2);
102+
return CommandResultType.DEFAULT;
103+
}
104+
105+
teleportRequest.accept();
106+
this.user.removeIncomingTeleportRequest(targetUser);
107+
}
38108

39109
return CommandResultType.SUCCESS;
40110
}

src/main/java/fr/maxlego08/essentials/commands/commands/teleport/CommandTeleportDeny.java

Lines changed: 82 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@
55
import fr.maxlego08.essentials.api.commands.Permission;
66
import fr.maxlego08.essentials.api.messages.Message;
77
import fr.maxlego08.essentials.api.user.TeleportRequest;
8+
import fr.maxlego08.essentials.api.user.User;
89
import fr.maxlego08.essentials.module.modules.TeleportationModule;
910
import fr.maxlego08.essentials.zutils.utils.commands.VCommand;
11+
import org.bukkit.OfflinePlayer;
12+
import org.bukkit.entity.Player;
13+
14+
import java.util.ArrayList;
15+
import java.util.Collection;
1016

1117
public class CommandTeleportDeny extends VCommand {
1218

@@ -15,26 +21,90 @@ public CommandTeleportDeny(EssentialsPlugin plugin) {
1521
this.setModule(TeleportationModule.class);
1622
this.setPermission(Permission.ESSENTIALS_TPA_DENY);
1723
this.setDescription(Message.DESCRIPTION_TPA_DENY);
24+
this.addOptionalArg("player");
1825
this.onlyPlayers();
1926
}
2027

2128
@Override
2229
protected CommandResultType perform(EssentialsPlugin plugin) {
2330

24-
TeleportRequest teleportRequest = this.user.getTeleportRequest();
25-
if (teleportRequest == null) {
26-
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE);
27-
return CommandResultType.DEFAULT;
28-
}
31+
String arg = this.argAsString(0, null);
2932

30-
if (!teleportRequest.isValid()) {
31-
this.user.setTeleportRequest(null);
32-
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE_2);
33-
return CommandResultType.DEFAULT;
34-
}
33+
if (arg == null) {
34+
// deny latest request
35+
TeleportRequest teleportRequest = this.user.getTeleportRequest();
36+
if (teleportRequest == null) {
37+
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE);
38+
return CommandResultType.DEFAULT;
39+
}
40+
41+
if (!teleportRequest.isValid()) {
42+
this.user.removeIncomingTeleportRequest(teleportRequest.getFromUser());
43+
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE_2);
44+
return CommandResultType.DEFAULT;
45+
}
46+
47+
teleportRequest.deny();
48+
this.user.removeIncomingTeleportRequest(teleportRequest.getFromUser());
49+
50+
} else if (arg.equals("*")) {
51+
// deny all pending requests
52+
Collection<TeleportRequest> requests = this.user.getIncomingTeleportRequests();
53+
if (requests.isEmpty()) {
54+
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE);
55+
return CommandResultType.DEFAULT;
56+
}
57+
58+
int count = 0;
59+
for (TeleportRequest request : new ArrayList<>(requests)) {
60+
if (request.isValid()) {
61+
request.deny();
62+
this.user.removeIncomingTeleportRequest(request.getFromUser());
63+
count++;
64+
}
65+
}
3566

36-
teleportRequest.deny();
37-
this.user.setTeleportRequest(null);
67+
if (count > 0) {
68+
message(sender, Message.COMMAND_TPA_DENY_ALL_SUCCESS, "%count%", count);
69+
} else {
70+
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE);
71+
return CommandResultType.DEFAULT;
72+
}
73+
74+
} else {
75+
// deny request from that player
76+
Player targetPlayer = this.argAsPlayer(0);
77+
User targetUser = null;
78+
79+
if (targetPlayer != null) {
80+
targetUser = plugin.getStorageManager().getStorage().getUser(targetPlayer.getUniqueId());
81+
} else {
82+
OfflinePlayer offlinePlayer = this.argAsOfflinePlayer(0);
83+
if (offlinePlayer != null && offlinePlayer.hasPlayedBefore()) {
84+
targetUser = plugin.getStorageManager().getStorage().getUser(offlinePlayer.getUniqueId());
85+
}
86+
}
87+
88+
if (targetUser == null) {
89+
message(sender, Message.PLAYER_NOT_FOUND, "%player%", arg);
90+
return CommandResultType.DEFAULT;
91+
}
92+
93+
TeleportRequest teleportRequest = this.user.getTeleportRequestFrom(targetUser);
94+
if (teleportRequest == null) {
95+
message(sender, Message.COMMAND_TPA_ERROR_NO_REQUEST_FROM_PLAYER, "%player%", targetUser.getName());
96+
return CommandResultType.DEFAULT;
97+
}
98+
99+
if (!teleportRequest.isValid()) {
100+
this.user.removeIncomingTeleportRequest(targetUser);
101+
message(sender, Message.COMMAND_TPA_ERROR_TO_LATE_2);
102+
return CommandResultType.DEFAULT;
103+
}
104+
105+
teleportRequest.deny();
106+
this.user.removeIncomingTeleportRequest(targetUser);
107+
}
38108

39109
return CommandResultType.SUCCESS;
40110
}

src/main/java/fr/maxlego08/essentials/user/ZUser.java

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public class ZUser extends ZUtils implements User {
4343

4444
private final EssentialsPlugin plugin;
4545
private final Map<UUID, TeleportRequest> teleports = new HashMap<>();
46+
private final Map<UUID, TeleportRequest> incomingTeleportRequests = new LinkedHashMap<>();
4647
private final Map<String, Long> cooldowns = new HashMap<>();
4748
private final UUID uniqueId;
4849
private final Map<Option, Boolean> options = new HashMap<>();
@@ -53,7 +54,6 @@ public class ZUser extends ZUtils implements User {
5354
private final Selection selection = new ZSelection();
5455
private WorldEditTask worldEditTask;
5556
private String name;
56-
private TeleportRequest teleportRequest;
5757
private User targetUser;
5858
private BigDecimal targetAmount;
5959
private Economy targetEconomy;
@@ -251,19 +251,65 @@ public Collection<TeleportRequest> getTeleportRequests() {
251251

252252
@Override
253253
public TeleportRequest getTeleportRequest() {
254-
return teleportRequest;
254+
this.incomingTeleportRequests.entrySet().removeIf(entry -> !entry.getValue().isValid());
255+
256+
TeleportRequest latestRequest = null;
257+
for (TeleportRequest request : this.incomingTeleportRequests.values()) {
258+
if (request.isValid()) {
259+
latestRequest = request;
260+
}
261+
}
262+
return latestRequest;
255263
}
256264

257265
@Override
258266
public void setTeleportRequest(TeleportRequest teleportRequest) {
259-
this.teleportRequest = teleportRequest;
267+
if (teleportRequest != null) {
268+
this.setIncomingTeleportRequest(teleportRequest);
269+
}
260270
}
261271

262272
@Override
263273
public void removeTeleportRequest(User user) {
264274
this.teleports.remove(user.getUniqueId());
265275
}
266276

277+
@Override
278+
public TeleportRequest getTeleportRequestFrom(User fromUser) {
279+
if (fromUser == null) return null;
280+
281+
// Cleanup expired requests
282+
this.incomingTeleportRequests.entrySet().removeIf(entry -> !entry.getValue().isValid());
283+
284+
TeleportRequest request = this.incomingTeleportRequests.get(fromUser.getUniqueId());
285+
return (request != null && request.isValid()) ? request : null;
286+
}
287+
288+
@Override
289+
public Collection<TeleportRequest> getIncomingTeleportRequests() {
290+
this.incomingTeleportRequests.entrySet().removeIf(entry -> !entry.getValue().isValid());
291+
292+
return this.incomingTeleportRequests.values().stream()
293+
.filter(TeleportRequest::isValid)
294+
.collect(Collectors.toList());
295+
}
296+
297+
@Override
298+
public void setIncomingTeleportRequest(TeleportRequest teleportRequest) {
299+
if (teleportRequest == null) return;
300+
301+
this.incomingTeleportRequests.entrySet().removeIf(entry -> !entry.getValue().isValid());
302+
303+
UUID fromUserId = teleportRequest.getFromUser().getUniqueId();
304+
this.incomingTeleportRequests.put(fromUserId, teleportRequest);
305+
}
306+
307+
@Override
308+
public void removeIncomingTeleportRequest(User fromUser) {
309+
if (fromUser == null) return;
310+
this.incomingTeleportRequests.remove(fromUser.getUniqueId());
311+
}
312+
267313
@Override
268314
public void teleportNow(Location location) {
269315
// ToDo, https://github.com/PaperMC/Folia/?tab=readme-ov-file#current-broken-api

0 commit comments

Comments
 (0)