Validating league format (with league collection).
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
package com.gempukku.lotro.game;
|
||||
|
||||
import com.gempukku.lotro.logic.vo.LotroDeck;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CollectionUtils {
|
||||
public static Map<String, Integer> getTotalCardCountForDeck(LotroDeck deck) {
|
||||
Map<String, Integer> counts = new HashMap<String, Integer>();
|
||||
String ring = deck.getRing();
|
||||
if (ring != null)
|
||||
incrementCardCount(counts, ring, 1);
|
||||
String ringBearer = deck.getRingBearer();
|
||||
if (ringBearer != null)
|
||||
incrementCardCount(counts, ringBearer, 1);
|
||||
for (String site : deck.getSites())
|
||||
incrementCardCount(counts, site, 1);
|
||||
for (String adventureCard : deck.getAdventureCards())
|
||||
incrementCardCount(counts, adventureCard, 1);
|
||||
return counts;
|
||||
}
|
||||
|
||||
private static void incrementCardCount(Map<String, Integer> map, String blueprintId, int incrementBy) {
|
||||
final Integer oldCount = map.get(blueprintId);
|
||||
if (oldCount == null)
|
||||
map.put(blueprintId, incrementBy);
|
||||
else
|
||||
map.put(blueprintId, oldCount + incrementBy);
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ public class HallServer extends AbstractServer {
|
||||
|
||||
private final int _playerInactivityPeriod = 1000 * 10; // 10 seconds
|
||||
|
||||
private Map<String, Long> _lastVisitedPlayers = Collections.synchronizedMap(new LinkedHashMap<String, Long>());
|
||||
private Map<Player, Long> _lastVisitedPlayers = Collections.synchronizedMap(new LinkedHashMap<Player, Long>());
|
||||
|
||||
public HallServer(LotroServer lotroServer, ChatServer chatServer, LeagueService leagueService, CollectionDAO collectionDao, boolean test) {
|
||||
_lotroServer = lotroServer;
|
||||
@@ -75,28 +75,33 @@ public class HallServer extends AbstractServer {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param playerId
|
||||
* @return If table created, otherwise <code>false</code> (if the user already is sitting at a table or playing).
|
||||
*/
|
||||
public synchronized void createNewTable(String type, String playerId, String deckName) throws HallException {
|
||||
LotroFormat supportedFormat = _supportedFormats.get(type);
|
||||
if (supportedFormat == null)
|
||||
public synchronized void createNewTable(String type, Player player, String deckName) throws HallException {
|
||||
LotroFormat format = _supportedFormats.get(type);
|
||||
// Maybe it's a league format?
|
||||
if (format == null) {
|
||||
final League league = _leagueService.getLeagueByType(type);
|
||||
if (league != null)
|
||||
format = _leagueService.getLeagueFormat(league, player);
|
||||
}
|
||||
if (format == null)
|
||||
throw new HallException("This format is not supported: " + type);
|
||||
|
||||
LotroDeck lotroDeck = validateUserAndDeck(type, supportedFormat, playerId, deckName);
|
||||
LotroDeck lotroDeck = validateUserAndDeck(type, format, player, deckName);
|
||||
|
||||
String tableId = String.valueOf(_nextTableId++);
|
||||
AwaitingTable table = new AwaitingTable(type, _supportedFormatNames.get(type), supportedFormat);
|
||||
AwaitingTable table = new AwaitingTable(type, _supportedFormatNames.get(type), format);
|
||||
_awaitingTables.put(tableId, table);
|
||||
|
||||
joinTableInternal(tableId, playerId, table, deckName, lotroDeck);
|
||||
joinTableInternal(tableId, player.getName(), table, deckName, lotroDeck);
|
||||
}
|
||||
|
||||
private LotroDeck validateUserAndDeck(String type, LotroFormat format, String playerId, String deckName) throws HallException {
|
||||
if (isPlayerBusy(playerId))
|
||||
private LotroDeck validateUserAndDeck(String type, LotroFormat format, Player player, String deckName) throws HallException {
|
||||
if (isPlayerBusy(player.getName()))
|
||||
throw new HallException("You can't play more than one game at a time or wait at more than one table");
|
||||
|
||||
LotroDeck lotroDeck = _lotroServer.getParticipantDeck(playerId, deckName);
|
||||
LotroDeck lotroDeck = _lotroServer.getParticipantDeck(player.getName(), deckName);
|
||||
if (lotroDeck == null)
|
||||
throw new HallException("You don't have a deck registered yet");
|
||||
|
||||
@@ -106,25 +111,23 @@ public class HallServer extends AbstractServer {
|
||||
throw new HallException("Your registered deck is not valid for this format: " + e.getMessage());
|
||||
}
|
||||
|
||||
Player player = _lotroServer.getPlayerDao().getPlayer(playerId);
|
||||
CardCollection collection = _collectionDao.getCollectionForPlayer(player, _formatCollectionIds.get(type));
|
||||
// CardCollection collection = _collectionDao.getCollectionForPlayer(player, _formatCollectionIds.get(type));
|
||||
// TODO check that player has cards in collection
|
||||
|
||||
return lotroDeck;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param playerId
|
||||
* @return If table joined, otherwise <code>false</code> (if the user already is sitting at a table or playing).
|
||||
*/
|
||||
public synchronized boolean joinTableAsPlayer(String tableId, String playerId, String deckName) throws HallException {
|
||||
public synchronized boolean joinTableAsPlayer(String tableId, Player player, String deckName) throws HallException {
|
||||
AwaitingTable awaitingTable = _awaitingTables.get(tableId);
|
||||
if (awaitingTable == null)
|
||||
throw new HallException("Table is already taken or was removed");
|
||||
|
||||
LotroDeck lotroDeck = validateUserAndDeck(awaitingTable.getFormatType(), awaitingTable.getLotroFormat(), playerId, deckName);
|
||||
LotroDeck lotroDeck = validateUserAndDeck(awaitingTable.getFormatType(), awaitingTable.getLotroFormat(), player, deckName);
|
||||
|
||||
joinTableInternal(tableId, playerId, awaitingTable, deckName, lotroDeck);
|
||||
joinTableInternal(tableId, player.getName(), awaitingTable, deckName, lotroDeck);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -146,11 +149,11 @@ public class HallServer extends AbstractServer {
|
||||
_awaitingTables.remove(tableId);
|
||||
}
|
||||
|
||||
public synchronized void leaveAwaitingTables(String playerId) {
|
||||
public synchronized void leaveAwaitingTables(Player player) {
|
||||
Map<String, AwaitingTable> copy = new HashMap<String, AwaitingTable>(_awaitingTables);
|
||||
for (Map.Entry<String, AwaitingTable> table : copy.entrySet()) {
|
||||
if (table.getValue().hasPlayer(playerId)) {
|
||||
boolean empty = table.getValue().removePlayer(playerId);
|
||||
if (table.getValue().hasPlayer(player.getName())) {
|
||||
boolean empty = table.getValue().removePlayer(player.getName());
|
||||
if (empty)
|
||||
_awaitingTables.remove(table.getKey());
|
||||
}
|
||||
@@ -164,9 +167,9 @@ public class HallServer extends AbstractServer {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void processTables(String participantId, HallInfoVisitor visitor) {
|
||||
_lastVisitedPlayers.put(participantId, System.currentTimeMillis());
|
||||
visitor.playerIsWaiting(isPlayerWaiting(participantId));
|
||||
public void processTables(Player player, HallInfoVisitor visitor) {
|
||||
_lastVisitedPlayers.put(player, System.currentTimeMillis());
|
||||
visitor.playerIsWaiting(isPlayerWaiting(player.getName()));
|
||||
|
||||
Map<String, AwaitingTable> copy = new HashMap<String, AwaitingTable>(_awaitingTables);
|
||||
for (Map.Entry<String, AwaitingTable> table : copy.entrySet())
|
||||
@@ -179,7 +182,7 @@ public class HallServer extends AbstractServer {
|
||||
visitor.visitTable(runningGame.getKey(), runningGame.getValue(), lotroGameMediator.getGameStatus(), _runningTableFormatNames.get(runningGame.getKey()), lotroGameMediator.getPlayersPlaying(), lotroGameMediator.getWinner());
|
||||
}
|
||||
|
||||
String playerTable = getNonFinishedPlayerTable(participantId);
|
||||
String playerTable = getNonFinishedPlayerTable(player.getName());
|
||||
if (playerTable != null) {
|
||||
String gameId = _runningTables.get(playerTable);
|
||||
if (gameId != null) {
|
||||
@@ -232,12 +235,12 @@ public class HallServer extends AbstractServer {
|
||||
}
|
||||
|
||||
long currentTime = System.currentTimeMillis();
|
||||
Map<String, Long> visitCopy = new LinkedHashMap<String, Long>(_lastVisitedPlayers);
|
||||
for (Map.Entry<String, Long> lastVisitedPlayer : visitCopy.entrySet()) {
|
||||
Map<Player, Long> visitCopy = new LinkedHashMap<Player, Long>(_lastVisitedPlayers);
|
||||
for (Map.Entry<Player, Long> lastVisitedPlayer : visitCopy.entrySet()) {
|
||||
if (currentTime > lastVisitedPlayer.getValue() + _playerInactivityPeriod) {
|
||||
String playerId = lastVisitedPlayer.getKey();
|
||||
_lastVisitedPlayers.remove(playerId);
|
||||
leaveAwaitingTables(playerId);
|
||||
Player player = lastVisitedPlayer.getKey();
|
||||
_lastVisitedPlayers.remove(player);
|
||||
leaveAwaitingTables(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,41 @@
|
||||
package com.gempukku.lotro.league;
|
||||
|
||||
import com.gempukku.lotro.common.Block;
|
||||
import com.gempukku.lotro.game.CardCollection;
|
||||
import com.gempukku.lotro.game.CollectionUtils;
|
||||
import com.gempukku.lotro.game.DeckInvalidException;
|
||||
import com.gempukku.lotro.game.LotroCardBlueprintLibrary;
|
||||
import com.gempukku.lotro.game.formats.DefaultLotroFormat;
|
||||
import com.gempukku.lotro.logic.vo.LotroDeck;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class LeagueFormat extends DefaultLotroFormat {
|
||||
private CardCollection _playerCardCollection;
|
||||
private boolean _orderedSites;
|
||||
|
||||
public LeagueFormat(LotroCardBlueprintLibrary library, boolean orderedSites) {
|
||||
public LeagueFormat(LotroCardBlueprintLibrary library, CardCollection playerCardCollection, boolean orderedSites) {
|
||||
super(library, Block.FELLOWSHIP, true, 60, Integer.MAX_VALUE, true, true);
|
||||
_playerCardCollection = playerCardCollection;
|
||||
_orderedSites = orderedSites;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateDeck(LotroDeck deck) throws DeckInvalidException {
|
||||
// First validate the deck is valid at all
|
||||
super.validateDeck(deck);
|
||||
|
||||
// Now check if player owns all the cards
|
||||
Map<String, Integer> deckCardCounts = CollectionUtils.getTotalCardCountForDeck(deck);
|
||||
final Map<String, Integer> collectionCardCounts = _playerCardCollection.getAll();
|
||||
|
||||
for (Map.Entry<String, Integer> cardCount : deckCardCounts.entrySet()) {
|
||||
final Integer collectionCount = collectionCardCounts.get(cardCount.getKey());
|
||||
if (collectionCount == null || collectionCount < cardCount.getValue())
|
||||
throw new DeckInvalidException("You don't have the required cards in collection for this format");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOrderedSites() {
|
||||
return _orderedSites;
|
||||
|
||||
@@ -49,7 +49,7 @@ public class LeagueService {
|
||||
return null;
|
||||
}
|
||||
|
||||
public LotroFormat getLeagueFormat(League league) {
|
||||
return new LeagueFormat(_library, true);
|
||||
public LotroFormat getLeagueFormat(League league, Player player) {
|
||||
return new LeagueFormat(_library, getLeagueCollection(player, league), true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -731,6 +731,12 @@ public class ServerResource {
|
||||
if (!_test)
|
||||
participantId = getLoggedUser(request);
|
||||
|
||||
PlayerDAO playerDao = _lotroServer.getPlayerDao();
|
||||
|
||||
Player player = playerDao.getPlayer(participantId);
|
||||
if (player == null)
|
||||
sendError(Response.Status.UNAUTHORIZED);
|
||||
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
|
||||
@@ -738,7 +744,7 @@ public class ServerResource {
|
||||
|
||||
Element hall = doc.createElement("hall");
|
||||
|
||||
_hallServer.processTables(participantId, new SerializeHallInfoVisitor(doc, hall));
|
||||
_hallServer.processTables(player, new SerializeHallInfoVisitor(doc, hall));
|
||||
for (Map.Entry<String, String> format : _hallServer.getSupportedFormatNames().entrySet()) {
|
||||
Element formatElem = doc.createElement("format");
|
||||
formatElem.setAttribute("type", format.getKey());
|
||||
@@ -768,8 +774,14 @@ public class ServerResource {
|
||||
if (!_test)
|
||||
participantId = getLoggedUser(request);
|
||||
|
||||
PlayerDAO playerDao = _lotroServer.getPlayerDao();
|
||||
|
||||
Player player = playerDao.getPlayer(participantId);
|
||||
if (player == null)
|
||||
sendError(Response.Status.UNAUTHORIZED);
|
||||
|
||||
try {
|
||||
_hallServer.joinTableAsPlayer(tableId, participantId, deckName);
|
||||
_hallServer.joinTableAsPlayer(tableId, player, deckName);
|
||||
return null;
|
||||
} catch (HallException e) {
|
||||
return marshalException(e);
|
||||
@@ -786,8 +798,14 @@ public class ServerResource {
|
||||
if (!_test)
|
||||
participantId = getLoggedUser(request);
|
||||
|
||||
PlayerDAO playerDao = _lotroServer.getPlayerDao();
|
||||
|
||||
Player player = playerDao.getPlayer(participantId);
|
||||
if (player == null)
|
||||
sendError(Response.Status.UNAUTHORIZED);
|
||||
|
||||
try {
|
||||
_hallServer.createNewTable(format, participantId, deckName);
|
||||
_hallServer.createNewTable(format, player, deckName);
|
||||
return null;
|
||||
} catch (HallException e) {
|
||||
return marshalException(e);
|
||||
@@ -802,7 +820,13 @@ public class ServerResource {
|
||||
if (!_test)
|
||||
participantId = getLoggedUser(request);
|
||||
|
||||
_hallServer.leaveAwaitingTables(participantId);
|
||||
PlayerDAO playerDao = _lotroServer.getPlayerDao();
|
||||
|
||||
Player player = playerDao.getPlayer(participantId);
|
||||
if (player == null)
|
||||
sendError(Response.Status.UNAUTHORIZED);
|
||||
|
||||
_hallServer.leaveAwaitingTables(player);
|
||||
}
|
||||
|
||||
@GET
|
||||
|
||||
Reference in New Issue
Block a user