Server/src/main/java/de/towerdefence/server/match/queue/MatchQueueService.java

144 lines
4.9 KiB
Java
Raw Normal View History

2025-02-26 13:26:58 +01:00
package de.towerdefence.server.match.queue;
import de.towerdefence.server.match.confirmation.*;
import de.towerdefence.server.player.Player;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@AllArgsConstructor
public class MatchQueueService {
private final static int REQUIRED_PLAYER_COUNT = 2;
@Autowired
private final MatchConfirmationService matchConfirmationService;
private final List<Player> queue = new ArrayList<>();
private final Map<Player, ConfirmationCallbacks> confirmationCallbacks = new HashMap<>();
public void queuePlayer(
Player player,
FoundCallback foundCallback,
QueuedCallback queuedCallback,
AbortCallback abortCallback,
EstablishedCallback establishedCallback) {
queue.add(player);
confirmationCallbacks.put(player, new ConfirmationCallbacks(
foundCallback,
queuedCallback,
abortCallback,
establishedCallback,
this::onRequeue));
tryMatching();
}
public void onRequeue(
Player player,
String matchId,
FoundCallback foundCallback,
QueuedCallback queuedCallback,
AbortCallback abortCallback,
EstablishedCallback establishedCallback) {
abortCallback.call(player, matchId);
try {
queuedCallback.call(player);
} catch (IOException ignored) {
return;
}
queuePlayer(player, foundCallback, queuedCallback, abortCallback, establishedCallback);
}
public void unQueuePlayer(Player player) {
queue.remove(player);
confirmationCallbacks.remove(player);
}
private void tryMatching() {
if (queue.size() < REQUIRED_PLAYER_COUNT) {
return;
}
List<Player> loopQueue = new ArrayList<>(queue);
for (int i = 0; i < loopQueue.size() / REQUIRED_PLAYER_COUNT; i++) {
Player player1 = loopQueue.get(REQUIRED_PLAYER_COUNT * i);
Player player2 = loopQueue.get(REQUIRED_PLAYER_COUNT * i + 1);
ConfirmationCallbacks player1Callbacks = confirmationCallbacks.get(player1);
ConfirmationCallbacks player2Callbacks = confirmationCallbacks.get(player2);
UnconfirmedMatch match = this.matchConfirmationService.createMatch(
player1,
player2,
player1Callbacks,
player2Callbacks);
sentMatchFound(
match,
player1,
player2,
player1Callbacks,
player2Callbacks);
}
if (queue.size() > REQUIRED_PLAYER_COUNT) {
tryMatching();
}
}
private void sentMatchFound(
UnconfirmedMatch match,
Player player1,
Player player2,
ConfirmationCallbacks player1Callbacks,
ConfirmationCallbacks player2Callbacks) {
boolean player1disconnected = setMatchFoundToPlayer(player1, player1Callbacks.getFoundCallback(), match);
boolean player2disconnected = setMatchFoundToPlayer(player2, player2Callbacks.getFoundCallback(), match);
queue.remove(player1);
queue.remove(player2);
if (!player1disconnected && !player2disconnected) {
return;
}
if (player1disconnected && match.getPlayer2State() != PlayerMatchConfirmState.ABORTED) {
player2Callbacks.getRequeueCallback().call(
player2,
match.getMatchId(),
player2Callbacks.getFoundCallback(),
player2Callbacks.getQueuedCallback(),
player2Callbacks.getAbortCallback(),
player2Callbacks.getEstablishedCallback());
}
if (player2disconnected && match.getPlayer1State() != PlayerMatchConfirmState.ABORTED) {
player1Callbacks.getRequeueCallback().call(
player1,
match.getMatchId(),
player1Callbacks.getFoundCallback(),
player1Callbacks.getQueuedCallback(),
player1Callbacks.getAbortCallback(),
player1Callbacks.getEstablishedCallback());
}
}
private boolean setMatchFoundToPlayer(Player player, FoundCallback callback, UnconfirmedMatch match) {
try {
callback.call(
player,
match.getMatchId(),
match.getCreated(),
UnconfirmedMatch.TTL);
} catch (IOException e) {
return true;
}
return false;
}
}