diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/CollectionUtils.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/CollectionUtils.java new file mode 100644 index 000000000..97cb93302 --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/CollectionUtils.java @@ -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 getTotalCardCountForDeck(LotroDeck deck) { + Map counts = new HashMap(); + 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 map, String blueprintId, int incrementBy) { + final Integer oldCount = map.get(blueprintId); + if (oldCount == null) + map.put(blueprintId, incrementBy); + else + map.put(blueprintId, oldCount + incrementBy); + } +} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/hall/HallServer.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/hall/HallServer.java index 7ef9e9e32..6ec12ad32 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/hall/HallServer.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/hall/HallServer.java @@ -31,7 +31,7 @@ public class HallServer extends AbstractServer { private final int _playerInactivityPeriod = 1000 * 10; // 10 seconds - private Map _lastVisitedPlayers = Collections.synchronizedMap(new LinkedHashMap()); + private Map _lastVisitedPlayers = Collections.synchronizedMap(new LinkedHashMap()); 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 false (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 false (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 copy = new HashMap(_awaitingTables); for (Map.Entry 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 copy = new HashMap(_awaitingTables); for (Map.Entry 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 visitCopy = new LinkedHashMap(_lastVisitedPlayers); - for (Map.Entry lastVisitedPlayer : visitCopy.entrySet()) { + Map visitCopy = new LinkedHashMap(_lastVisitedPlayers); + for (Map.Entry 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); } } } diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueFormat.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueFormat.java index 942dba253..f50af6dd2 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueFormat.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueFormat.java @@ -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 deckCardCounts = CollectionUtils.getTotalCardCountForDeck(deck); + final Map collectionCardCounts = _playerCardCollection.getAll(); + + for (Map.Entry 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; diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueService.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueService.java index 70f0f322f..5b2d8dc2d 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueService.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueService.java @@ -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); } } diff --git a/gemp-lotr/gemp-lotr-web/src/main/java/com/gempukku/lotro/server/ServerResource.java b/gemp-lotr/gemp-lotr-web/src/main/java/com/gempukku/lotro/server/ServerResource.java index 6c1db3570..f83d43451 100644 --- a/gemp-lotr/gemp-lotr-web/src/main/java/com/gempukku/lotro/server/ServerResource.java +++ b/gemp-lotr/gemp-lotr-web/src/main/java/com/gempukku/lotro/server/ServerResource.java @@ -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 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