TD-50 Add Money to Matchdata
All checks were successful
Quality Check / Validate OAS (push) Successful in 36s
Quality Check / Validate OAS (pull_request) Successful in 38s
Quality Check / Testing (push) Successful in 1m17s
Quality Check / Linting (push) Successful in 1m18s
Quality Check / Static Analysis (push) Successful in 1m24s
Quality Check / Linting (pull_request) Successful in 1m7s
Quality Check / Static Analysis (pull_request) Successful in 1m11s
Quality Check / Testing (pull_request) Successful in 44s

This commit is contained in:
Kevin Schmidt 2025-03-12 12:15:25 +01:00
parent b849cd7a27
commit 831359eea9
6 changed files with 161 additions and 1 deletions

View file

@ -1,22 +1,37 @@
package de.towerdefence.server.match;
import de.towerdefence.server.player.Player;
import de.towerdefence.server.server.channels.match.money.PlayerMoneyCallback;
import de.towerdefence.server.server.channels.match.placing.InvalidPlacementReason;
import de.towerdefence.server.server.channels.match.placing.Tower;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
import java.util.Optional;
@Getter
public class Match {
public final static int MAP_SIZE_X = 10;
public final static int MAP_SIZE_Y = 20;
public final static int START_MONEY = 50;
private final String matchId;
private final Player player1;
private final Player player2;
private int player1Money = START_MONEY;
private int player2Money = START_MONEY;
private PlayerMoneyCallback player1MoneyCallback;
private PlayerMoneyCallback player2MoneyCallback;
private final Tower[][] player1Map = new Tower[MAP_SIZE_X][MAP_SIZE_Y];
private final Tower[][] player2Map = new Tower[MAP_SIZE_X][MAP_SIZE_Y];
private boolean isPlayer1Connected = false;
private boolean isPlayer2Connected = false;
public Match(String matchId, Player player1, Player player2) {
this.matchId = matchId;
this.player1 = player1;
this.player2 = player2;
}
public Player getOpponent(Player player) {
boolean isPlayer1 = player1.equals(player);
@ -53,4 +68,53 @@ public class Match {
}
return getOpponent(player);
}
// INFO: MoneyHandling
public Optional<Integer> getPlayerMoney(Player player) {
if (player != player1 && player != player2) {
return Optional.empty();
}
if (player == player1) {
return Optional.of(player1Money);
} else {
return Optional.of(player2Money);
}
}
public void addMoney(int money) {
player1Money += money;
player2Money += money;
}
public void removeMoney(Player player, int money) {
if (player == player1) {
player1Money -= money;
}
if (player == player2) {
player2Money -= money;
}
}
public void setPlayerMoneyCallback( Player player, PlayerMoneyCallback playerMoneyCallback) {
if (player == player1) {
this.player1MoneyCallback = playerMoneyCallback;
}
if (player == player2) {
this.player2MoneyCallback = playerMoneyCallback;
}
}
/**
* @return true if both players are connected
*/
public boolean setPlayerConnected(Player player) {
if (player == player1) {
isPlayer1Connected = true;
}
if (player == player2) {
isPlayer2Connected = true;
}
return isPlayer1Connected && isPlayer2Connected;
}
}

View file

@ -1,15 +1,20 @@
package de.towerdefence.server.match;
import de.towerdefence.server.player.Player;
import de.towerdefence.server.server.channels.match.money.PlayerMoneyCallback;
import de.towerdefence.server.server.channels.match.placing.Tower;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.*;
@Service
public class MatchService {
private final Map<Player, Match> playerMatches = new HashMap<>();
private final Map<Match, ScheduledFuture<?>> moneyTasks = new HashMap<>();
private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
public void createMatch(String matchId, Player player1, Player player2) {
Match match = new Match(matchId, player1, player2);
@ -26,6 +31,31 @@ public class MatchService {
*/
public Player placeTower(Player player, int x, int y) throws InvalidPlacementException {
return playerMatches.get(player).addTower(player, new Tower(), x, y);
}
public void playerConnected(Player player, PlayerMoneyCallback callback) {
Match match = playerMatches.get(player);
Optional<Integer> currentMoney = match.getPlayerMoney(player);
if (currentMoney.isEmpty()) {
return;
}
match.setPlayerMoneyCallback(player, callback);
callback.call(player, currentMoney.get());
boolean matchStarted =match.setPlayerConnected(player);
if (!matchStarted) {
return;
}
ScheduledFuture<?> moneyTask = scheduler.scheduleAtFixedRate(
() -> {
match.addMoney(3);
match.getPlayer1MoneyCallback().call(match.getPlayer1(), match.getPlayer1Money());
match.getPlayer2MoneyCallback().call(match.getPlayer2(), match.getPlayer2Money());
},
5,
5,
TimeUnit.SECONDS
);
moneyTasks.put(match, moneyTask);
}
}

View file

@ -5,6 +5,7 @@ import de.towerdefence.server.match.InvalidPlacementException;
import de.towerdefence.server.match.MatchService;
import de.towerdefence.server.player.Player;
import de.towerdefence.server.server.JsonWebsocketHandler;
import de.towerdefence.server.server.channels.match.money.PlayerMoneyMessage;
import de.towerdefence.server.server.channels.match.placing.GamePlayerMap;
import de.towerdefence.server.server.channels.match.placing.InvalidPlacementMessage;
import de.towerdefence.server.server.channels.match.placing.RequestTowerPlacingMessage;
@ -35,6 +36,15 @@ public class MatchWebsocketHandler extends JsonWebsocketHandler {
public void afterConnectionEstablished(WebSocketSession session) {
super.afterConnectionEstablished(session);
playerSessions.put(sessionPlayers.get(session), session);
matchService.playerConnected(sessionPlayers.get(session), this::onPlayerMoneyChanged);
}
private void onPlayerMoneyChanged(Player player, int playerMoney) {
WebSocketSession session = playerSessions.get(player);
try {
new PlayerMoneyMessage(playerMoney).send(session);
} catch (IOException ignored) {
}
}
@Override

View file

@ -0,0 +1,8 @@
package de.towerdefence.server.server.channels.match.money;
import de.towerdefence.server.player.Player;
@FunctionalInterface
public interface PlayerMoneyCallback {
void call(Player player, int playerMoney);
}

View file

@ -0,0 +1,26 @@
package de.towerdefence.server.server.channels.match.money;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import de.towerdefence.server.server.JsonMessage;
import lombok.AllArgsConstructor;
import java.util.Map;
@AllArgsConstructor
public class PlayerMoneyMessage extends JsonMessage {
private final int playerMoney;
@Override
protected String getMessageId() {
return "PlayerMoney";
}
@Override
protected Map<String, JsonNode> getData(JsonNodeFactory factory) {
return Map.of(
"playerMoney", factory.numberNode(this.playerMoney)
);
}
}

View file

@ -241,6 +241,21 @@ channels:
- x
- y
- reason
PlayerMoney:
description: Money a player currently has
payload:
type: object
additionalProperties: false
properties:
$id:
type: string
format: messageId
playerMoney:
type: integer
required:
- $id
- playerMoney
operations:
requestConnectionToken:
@ -322,6 +337,13 @@ operations:
$ref: "#/channels/match"
messages:
- $ref: "#/channels/match/messages/TowerPlaced"
playerMoney:
title: PlayerMoney
action: receive
channel:
$ref: "#/channels/match"
messages:
- $ref: "#/channels/match/messages/PlayerMoney"