Skip to content

Commit e389ad2

Browse files
feat: added all extra features of aquarium map in murder mystery
1 parent 1f7b531 commit e389ad2

31 files changed

Lines changed: 2099 additions & 37 deletions

File tree

commons/src/main/java/net/swofty/commons/party/events/response/PartyWarpOverviewResponseEvent.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,33 @@
55
import net.swofty.commons.protocol.Serializer;
66
import org.json.JSONObject;
77

8+
import java.util.HashMap;
89
import java.util.List;
10+
import java.util.Map;
911
import java.util.UUID;
1012

1113
public class PartyWarpOverviewResponseEvent extends PartyResponseEvent {
1214
private final UUID warper;
1315
private final List<UUID> successfullyWarped;
1416
private final List<UUID> failedToWarp;
17+
private final Map<UUID, String> failureReasons;
1518

1619
public PartyWarpOverviewResponseEvent(FullParty party, UUID warper, List<UUID> successfullyWarped, List<UUID> failedToWarp) {
20+
this(party, warper, successfullyWarped, failedToWarp, new HashMap<>());
21+
}
22+
23+
public PartyWarpOverviewResponseEvent(FullParty party, UUID warper, List<UUID> successfullyWarped, List<UUID> failedToWarp, Map<UUID, String> failureReasons) {
1724
super(party);
1825
this.warper = warper;
1926
this.successfullyWarped = successfullyWarped;
2027
this.failedToWarp = failedToWarp;
28+
this.failureReasons = failureReasons != null ? failureReasons : new HashMap<>();
2129
}
2230

2331
public UUID getWarper() { return warper; }
2432
public List<UUID> getSuccessfullyWarped() { return successfullyWarped; }
2533
public List<UUID> getFailedToWarp() { return failedToWarp; }
34+
public Map<UUID, String> getFailureReasons() { return failureReasons; }
2635

2736

2837
@Override
@@ -40,6 +49,13 @@ public String serialize(PartyWarpOverviewResponseEvent value) {
4049
List<String> failedToWarp = value.failedToWarp.stream().map(UUID::toString).toList();
4150
json.put("failedToWarp", failedToWarp);
4251

52+
// Serialize failure reasons
53+
JSONObject failureReasonsJson = new JSONObject();
54+
for (Map.Entry<UUID, String> entry : value.failureReasons.entrySet()) {
55+
failureReasonsJson.put(entry.getKey().toString(), entry.getValue());
56+
}
57+
json.put("failureReasons", failureReasonsJson);
58+
4359
return json.toString();
4460
}
4561

@@ -62,12 +78,24 @@ public PartyWarpOverviewResponseEvent deserialize(String json) {
6278
return null;
6379
}
6480
}).toList();
65-
return new PartyWarpOverviewResponseEvent(party, warper, successfullyWarped, failedToWarp);
81+
82+
// Deserialize failure reasons
83+
Map<UUID, String> failureReasons = new HashMap<>();
84+
if (jsonObject.has("failureReasons")) {
85+
JSONObject failureReasonsJson = jsonObject.getJSONObject("failureReasons");
86+
for (String key : failureReasonsJson.keySet()) {
87+
try {
88+
failureReasons.put(UUID.fromString(key), failureReasonsJson.getString(key));
89+
} catch (Exception ignored) {}
90+
}
91+
}
92+
93+
return new PartyWarpOverviewResponseEvent(party, warper, successfullyWarped, failedToWarp, failureReasons);
6694
}
6795

6896
@Override
6997
public PartyWarpOverviewResponseEvent clone(PartyWarpOverviewResponseEvent value) {
70-
return new PartyWarpOverviewResponseEvent((FullParty) value.getParty(), value.warper, value.successfullyWarped, value.failedToWarp);
98+
return new PartyWarpOverviewResponseEvent((FullParty) value.getParty(), value.warper, value.successfullyWarped, value.failedToWarp, new HashMap<>(value.failureReasons));
7199
}
72100
};
73101
}

service.orchestrator/src/main/java/net/swofty/service/orchestrator/OrchestratorCache.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,35 @@ public static void handleHeartbeat(UUID uuid,
4343
* Finds an existing joinable game for the specified game type and map (Bedwars-specific)
4444
*/
4545
public static GameWithServer findExisting(BedwarsGameType gameType, String map) {
46-
return findExisting(ServerType.BEDWARS_GAME, gameType.maxPlayers(), map);
46+
return findExisting(ServerType.BEDWARS_GAME, gameType.maxPlayers(), map, 1);
47+
}
48+
49+
/**
50+
* Finds an existing joinable game for the specified game type and map with needed slots (Bedwars-specific)
51+
*/
52+
public static GameWithServer findExisting(BedwarsGameType gameType, String map, int neededSlots) {
53+
return findExisting(ServerType.BEDWARS_GAME, gameType.maxPlayers(), map, neededSlots);
4754
}
4855

4956
/**
5057
* Generic version - finds an existing joinable game for any server type
5158
*/
5259
public static GameWithServer findExisting(ServerType serverType, int maxPlayers, String map) {
60+
return findExisting(serverType, maxPlayers, map, 1);
61+
}
62+
63+
/**
64+
* Finds an existing joinable game with at least neededSlots available slots
65+
*/
66+
public static GameWithServer findExisting(ServerType serverType, int maxPlayers, String map, int neededSlots) {
5367
cleanup();
5468

5569
List<GameWithServer> candidates = new ArrayList<>();
5670
for (GameWithServer gameWithServer : gamesByGameId.values()) {
5771
Game game = gameWithServer.game();
72+
int availableSlots = maxPlayers - game.getInvolvedPlayers().size();
5873
if (game.getType() == serverType &&
59-
game.getInvolvedPlayers().size() < maxPlayers &&
74+
availableSlots >= neededSlots &&
6075
(map == null || game.getMap().equals(map))) {
6176
candidates.add(gameWithServer);
6277
}

service.orchestrator/src/main/java/net/swofty/service/orchestrator/endpoints/GetServerForMapEndpoint.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ private GetServerForMapProtocolObject.GetServerForMapResponse handleBedwars(
4343
return new GetServerForMapProtocolObject.GetServerForMapResponse(null, null);
4444
}
4545

46-
// First, try to find an existing joinable game
47-
OrchestratorCache.GameWithServer existingGameWithServer = OrchestratorCache.findExisting(gameType, body.map());
46+
int neededSlots = body.neededSlots() > 0 ? body.neededSlots() : 1;
47+
48+
// First, try to find an existing joinable game with enough slots
49+
OrchestratorCache.GameWithServer existingGameWithServer = OrchestratorCache.findExisting(gameType, body.map(), neededSlots);
4850
if (existingGameWithServer != null) {
4951
OrchestratorCache.GameServerState hostingServer = OrchestratorCache.getServerByUuid(existingGameWithServer.serverUuid());
5052
if (hostingServer != null) {
@@ -110,9 +112,11 @@ private GetServerForMapProtocolObject.GetServerForMapResponse handleMurderMyster
110112
return new GetServerForMapProtocolObject.GetServerForMapResponse(null, null);
111113
}
112114

113-
// First, try to find an existing joinable game
115+
int neededSlots = body.neededSlots() > 0 ? body.neededSlots() : 1;
116+
117+
// First, try to find an existing joinable game with enough slots
114118
OrchestratorCache.GameWithServer existingGameWithServer = OrchestratorCache.findExisting(
115-
ServerType.MURDER_MYSTERY_GAME, gameType.getMaxPlayers(), body.map());
119+
ServerType.MURDER_MYSTERY_GAME, gameType.getMaxPlayers(), body.map(), neededSlots);
116120
if (existingGameWithServer != null) {
117121
OrchestratorCache.GameServerState hostingServer = OrchestratorCache.getServerByUuid(existingGameWithServer.serverUuid());
118122
if (hostingServer != null) {

service.party/src/main/java/net/swofty/service/party/PartyCache.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import org.json.JSONObject;
1111

1212
import java.util.ArrayList;
13+
import java.util.HashMap;
1314
import java.util.List;
1415
import java.util.Map;
1516
import java.util.UUID;
@@ -276,10 +277,22 @@ public static void handleWarpRequest(PartyWarpRequestEvent event) {
276277
List<UUID> intendedToWarp = party.getParticipants().stream().filter(uuid -> !uuid.equals(warperUUID)).toList();
277278
Map<UUID, JSONObject> responses = ServiceToServerManager.sendToAllServers(FromServiceChannels.PROPAGATE_PARTY_EVENT, message, 3000).join();
278279
List<UUID> actualWarped = new ArrayList<>();
280+
Map<UUID, String> failureReasons = new HashMap<>();
281+
279282
for (JSONObject response : responses.values()) {
280283
boolean success = response.getBoolean("success");
281284

282-
if (!success) continue;
285+
// Check if the warp was blocked (e.g., game already started)
286+
if (!success) {
287+
if (response.optBoolean("blocked", false)) {
288+
String blockReason = response.optString("blockReason", "Unable to warp");
289+
// Apply block reason to all intended warp targets
290+
for (UUID uuid : intendedToWarp) {
291+
failureReasons.put(uuid, blockReason);
292+
}
293+
}
294+
continue;
295+
}
283296

284297
List<UUID> playersHandledUuids = response.getJSONArray("playersHandledUUIDs")
285298
.toList().stream().map(object -> {
@@ -295,6 +308,18 @@ public static void handleWarpRequest(PartyWarpRequestEvent event) {
295308
actualWarped.add(uuid);
296309
}
297310
}
311+
312+
// Collect rejection reasons from server response
313+
if (response.has("rejectedPlayers")) {
314+
JSONObject rejectedPlayers = response.getJSONObject("rejectedPlayers");
315+
for (String key : rejectedPlayers.keySet()) {
316+
try {
317+
UUID rejectedUuid = UUID.fromString(key);
318+
String reason = rejectedPlayers.getString(key);
319+
failureReasons.put(rejectedUuid, reason);
320+
} catch (Exception ignored) {}
321+
}
322+
}
298323
}
299324

300325
List<UUID> didNotWarp = new ArrayList<>();
@@ -304,7 +329,7 @@ public static void handleWarpRequest(PartyWarpRequestEvent event) {
304329
}
305330
});
306331

307-
PartyWarpOverviewResponseEvent warpOverviewResponse = new PartyWarpOverviewResponseEvent(party, warperUUID, actualWarped, didNotWarp);
332+
PartyWarpOverviewResponseEvent warpOverviewResponse = new PartyWarpOverviewResponseEvent(party, warperUUID, actualWarped, didNotWarp, failureReasons);
308333
sendEvent(warpOverviewResponse);
309334
}
310335

type.bedwarsgame/src/main/java/net/swofty/type/bedwarsgame/game/Game.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,24 @@ private boolean hasCapacityForPlayer() {
465465
return players.size() < getMaxPlayers();
466466
}
467467

468+
public boolean canAcceptNewPlayers() {
469+
return gameStatus == GameStatus.WAITING;
470+
}
471+
472+
public int getAvailableSlots() {
473+
return Math.max(0, getMaxPlayers() - players.size());
474+
}
475+
476+
public String canAcceptPartyWarp() {
477+
if (gameStatus == GameStatus.IN_PROGRESS) {
478+
return "Cannot warp - game has already started";
479+
}
480+
if (gameStatus == GameStatus.ENDING) {
481+
return "Cannot warp - game is ending";
482+
}
483+
return null;
484+
}
485+
468486
private boolean hasMinimumPlayersForStart() {
469487
int teamSize = Math.max(1, bedwarsGameType.getTeamSize());
470488
int teamCount = mapEntry.getConfiguration().getTeams().size();

0 commit comments

Comments
 (0)