Validating league format (with league collection).

This commit is contained in:
marcins78@gmail.com
2011-12-02 16:35:49 +00:00
parent a1b93a1dc3
commit 8d00765eb9
5 changed files with 118 additions and 36 deletions

View File

@@ -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);
}
}

View File

@@ -31,7 +31,7 @@ public class HallServer extends AbstractServer {
private final int _playerInactivityPeriod = 1000 * 10; // 10 seconds 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) { public HallServer(LotroServer lotroServer, ChatServer chatServer, LeagueService leagueService, CollectionDAO collectionDao, boolean test) {
_lotroServer = lotroServer; _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). * @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 { public synchronized void createNewTable(String type, Player player, String deckName) throws HallException {
LotroFormat supportedFormat = _supportedFormats.get(type); LotroFormat format = _supportedFormats.get(type);
if (supportedFormat == null) // 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); 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++); 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); _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 { private LotroDeck validateUserAndDeck(String type, LotroFormat format, Player player, String deckName) throws HallException {
if (isPlayerBusy(playerId)) 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"); 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) if (lotroDeck == null)
throw new HallException("You don't have a deck registered yet"); 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()); 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 // TODO check that player has cards in collection
return lotroDeck; return lotroDeck;
} }
/** /**
* @param playerId
* @return If table joined, otherwise <code>false</code> (if the user already is sitting at a table or playing). * @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); AwaitingTable awaitingTable = _awaitingTables.get(tableId);
if (awaitingTable == null) if (awaitingTable == null)
throw new HallException("Table is already taken or was removed"); 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; return true;
} }
@@ -146,11 +149,11 @@ public class HallServer extends AbstractServer {
_awaitingTables.remove(tableId); _awaitingTables.remove(tableId);
} }
public synchronized void leaveAwaitingTables(String playerId) { public synchronized void leaveAwaitingTables(Player player) {
Map<String, AwaitingTable> copy = new HashMap<String, AwaitingTable>(_awaitingTables); Map<String, AwaitingTable> copy = new HashMap<String, AwaitingTable>(_awaitingTables);
for (Map.Entry<String, AwaitingTable> table : copy.entrySet()) { for (Map.Entry<String, AwaitingTable> table : copy.entrySet()) {
if (table.getValue().hasPlayer(playerId)) { if (table.getValue().hasPlayer(player.getName())) {
boolean empty = table.getValue().removePlayer(playerId); boolean empty = table.getValue().removePlayer(player.getName());
if (empty) if (empty)
_awaitingTables.remove(table.getKey()); _awaitingTables.remove(table.getKey());
} }
@@ -164,9 +167,9 @@ public class HallServer extends AbstractServer {
return false; return false;
} }
public void processTables(String participantId, HallInfoVisitor visitor) { public void processTables(Player player, HallInfoVisitor visitor) {
_lastVisitedPlayers.put(participantId, System.currentTimeMillis()); _lastVisitedPlayers.put(player, System.currentTimeMillis());
visitor.playerIsWaiting(isPlayerWaiting(participantId)); visitor.playerIsWaiting(isPlayerWaiting(player.getName()));
Map<String, AwaitingTable> copy = new HashMap<String, AwaitingTable>(_awaitingTables); Map<String, AwaitingTable> copy = new HashMap<String, AwaitingTable>(_awaitingTables);
for (Map.Entry<String, AwaitingTable> table : copy.entrySet()) 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()); 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) { if (playerTable != null) {
String gameId = _runningTables.get(playerTable); String gameId = _runningTables.get(playerTable);
if (gameId != null) { if (gameId != null) {
@@ -232,12 +235,12 @@ public class HallServer extends AbstractServer {
} }
long currentTime = System.currentTimeMillis(); long currentTime = System.currentTimeMillis();
Map<String, Long> visitCopy = new LinkedHashMap<String, Long>(_lastVisitedPlayers); Map<Player, Long> visitCopy = new LinkedHashMap<Player, Long>(_lastVisitedPlayers);
for (Map.Entry<String, Long> lastVisitedPlayer : visitCopy.entrySet()) { for (Map.Entry<Player, Long> lastVisitedPlayer : visitCopy.entrySet()) {
if (currentTime > lastVisitedPlayer.getValue() + _playerInactivityPeriod) { if (currentTime > lastVisitedPlayer.getValue() + _playerInactivityPeriod) {
String playerId = lastVisitedPlayer.getKey(); Player player = lastVisitedPlayer.getKey();
_lastVisitedPlayers.remove(playerId); _lastVisitedPlayers.remove(player);
leaveAwaitingTables(playerId); leaveAwaitingTables(player);
} }
} }
} }

View File

@@ -1,17 +1,41 @@
package com.gempukku.lotro.league; package com.gempukku.lotro.league;
import com.gempukku.lotro.common.Block; 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.LotroCardBlueprintLibrary;
import com.gempukku.lotro.game.formats.DefaultLotroFormat; import com.gempukku.lotro.game.formats.DefaultLotroFormat;
import com.gempukku.lotro.logic.vo.LotroDeck;
import java.util.Map;
public class LeagueFormat extends DefaultLotroFormat { public class LeagueFormat extends DefaultLotroFormat {
private CardCollection _playerCardCollection;
private boolean _orderedSites; 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); super(library, Block.FELLOWSHIP, true, 60, Integer.MAX_VALUE, true, true);
_playerCardCollection = playerCardCollection;
_orderedSites = orderedSites; _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 @Override
public boolean isOrderedSites() { public boolean isOrderedSites() {
return _orderedSites; return _orderedSites;

View File

@@ -49,7 +49,7 @@ public class LeagueService {
return null; return null;
} }
public LotroFormat getLeagueFormat(League league) { public LotroFormat getLeagueFormat(League league, Player player) {
return new LeagueFormat(_library, true); return new LeagueFormat(_library, getLeagueCollection(player, league), true);
} }
} }

View File

@@ -731,6 +731,12 @@ public class ServerResource {
if (!_test) if (!_test)
participantId = getLoggedUser(request); participantId = getLoggedUser(request);
PlayerDAO playerDao = _lotroServer.getPlayerDao();
Player player = playerDao.getPlayer(participantId);
if (player == null)
sendError(Response.Status.UNAUTHORIZED);
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
@@ -738,7 +744,7 @@ public class ServerResource {
Element hall = doc.createElement("hall"); 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()) { for (Map.Entry<String, String> format : _hallServer.getSupportedFormatNames().entrySet()) {
Element formatElem = doc.createElement("format"); Element formatElem = doc.createElement("format");
formatElem.setAttribute("type", format.getKey()); formatElem.setAttribute("type", format.getKey());
@@ -768,8 +774,14 @@ public class ServerResource {
if (!_test) if (!_test)
participantId = getLoggedUser(request); participantId = getLoggedUser(request);
PlayerDAO playerDao = _lotroServer.getPlayerDao();
Player player = playerDao.getPlayer(participantId);
if (player == null)
sendError(Response.Status.UNAUTHORIZED);
try { try {
_hallServer.joinTableAsPlayer(tableId, participantId, deckName); _hallServer.joinTableAsPlayer(tableId, player, deckName);
return null; return null;
} catch (HallException e) { } catch (HallException e) {
return marshalException(e); return marshalException(e);
@@ -786,8 +798,14 @@ public class ServerResource {
if (!_test) if (!_test)
participantId = getLoggedUser(request); participantId = getLoggedUser(request);
PlayerDAO playerDao = _lotroServer.getPlayerDao();
Player player = playerDao.getPlayer(participantId);
if (player == null)
sendError(Response.Status.UNAUTHORIZED);
try { try {
_hallServer.createNewTable(format, participantId, deckName); _hallServer.createNewTable(format, player, deckName);
return null; return null;
} catch (HallException e) { } catch (HallException e) {
return marshalException(e); return marshalException(e);
@@ -802,7 +820,13 @@ public class ServerResource {
if (!_test) if (!_test)
participantId = getLoggedUser(request); 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 @GET