diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatRoom.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatRoom.java index 9727a8a59..04a42232f 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatRoom.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatRoom.java @@ -8,7 +8,6 @@ public class ChatRoom { private Map _chatRoomListeners = new HashMap(); public ChatRoom() { - postMessage("System", "Welcome to the room"); } public void postMessage(String from, String message) { diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatServer.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatServer.java index 7167cff33..5d63ca993 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatServer.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatServer.java @@ -9,7 +9,9 @@ public class ChatServer extends AbstractServer { private Map _chatRooms = new ConcurrentHashMap(); public void createChatRoom(String name) { - _chatRooms.put(name, new ChatRoomMediator()); + ChatRoomMediator chatRoom = new ChatRoomMediator(); + chatRoom.sendMessage("System", "Welcome to room: " + name); + _chatRooms.put(name, chatRoom); } public ChatRoomMediator getChatRoom(String name) { diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/DeckInvalidException.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/DeckInvalidException.java new file mode 100644 index 000000000..fc1d89175 --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/DeckInvalidException.java @@ -0,0 +1,7 @@ +package com.gempukku.lotro.game; + +public class DeckInvalidException extends Exception { + public DeckInvalidException(String message) { + super(message); + } +} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/DefaultLotroFormat.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/DefaultLotroFormat.java deleted file mode 100644 index 419546032..000000000 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/DefaultLotroFormat.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.gempukku.lotro.game; - -import com.gempukku.lotro.logic.vo.LotroDeck; - -public class DefaultLotroFormat implements LotroFormat { - private boolean _orderedSites; - - public DefaultLotroFormat(boolean orderedSites) { - _orderedSites = orderedSites; - } - - @Override - public boolean isOrderedSites() { - return _orderedSites; - } - - @Override - public boolean validateDeck(LotroDeck deck) { - return (deck != null); - } -} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroFormat.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroFormat.java deleted file mode 100644 index e5a1fd62f..000000000 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroFormat.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gempukku.lotro.game; - -import com.gempukku.lotro.logic.vo.LotroDeck; - -public interface LotroFormat { - public boolean isOrderedSites(); - - public boolean validateDeck(LotroDeck deck); -} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroGameMediator.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroGameMediator.java index 29a2e3599..59a6c70af 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroGameMediator.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroGameMediator.java @@ -1,6 +1,7 @@ package com.gempukku.lotro.game; import com.gempukku.lotro.common.CardType; +import com.gempukku.lotro.game.formats.LotroFormat; import com.gempukku.lotro.game.state.GameState; import com.gempukku.lotro.game.state.Skirmish; import com.gempukku.lotro.logic.decisions.AwaitingDecision; diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroServer.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroServer.java index 8265013f8..d0584965c 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroServer.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/LotroServer.java @@ -9,6 +9,7 @@ import com.gempukku.lotro.db.DeckDAO; import com.gempukku.lotro.db.PlayerDAO; import com.gempukku.lotro.db.vo.Deck; import com.gempukku.lotro.db.vo.Player; +import com.gempukku.lotro.game.formats.LotroFormat; import com.gempukku.lotro.logic.timing.GameResultListener; import com.gempukku.lotro.logic.vo.LotroDeck; import org.apache.log4j.Logger; @@ -58,6 +59,10 @@ public class LotroServer extends AbstractServer { _deckDao = new DeckDAO(dbAccess); } + public LotroCardBlueprintLibrary getLotroCardBlueprintLibrary() { + return _lotroCardBlueprintLibrary; + } + public PlayerDAO getPlayerDao() { return _playerDao; } diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/formats/DefaultLotroFormat.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/formats/DefaultLotroFormat.java new file mode 100644 index 000000000..bbdd8615a --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/formats/DefaultLotroFormat.java @@ -0,0 +1,123 @@ +package com.gempukku.lotro.game.formats; + +import com.gempukku.lotro.common.CardType; +import com.gempukku.lotro.common.Keyword; +import com.gempukku.lotro.common.Side; +import com.gempukku.lotro.game.DeckInvalidException; +import com.gempukku.lotro.game.LotroCardBlueprint; +import com.gempukku.lotro.game.LotroCardBlueprintLibrary; +import com.gempukku.lotro.logic.vo.LotroDeck; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public abstract class DefaultLotroFormat implements LotroFormat { + private LotroCardBlueprintLibrary _library; + private boolean _validateShadowFPCount = true; + private int _maximumSameName = 4; + private int _minimumDeckSize = 60; + private Set _restrictedCard = new HashSet(); + + public DefaultLotroFormat(LotroCardBlueprintLibrary library, boolean validateShadowFPCount, int minimumDeckSize, int maximumSameName) { + _library = library; + _validateShadowFPCount = validateShadowFPCount; + _minimumDeckSize = minimumDeckSize; + _maximumSameName = maximumSameName; + } + + protected void addRestrictedCard(String name) { + _restrictedCard.add(name); + } + + @Override + public void validateDeck(LotroDeck deck) throws DeckInvalidException { + try { + // Ring-bearer + if (deck.getRingBearer() == null) + throw new DeckInvalidException("Deck doesn't have a Ring-bearer"); + LotroCardBlueprint ringBearer = _library.getLotroCardBlueprint(deck.getRingBearer()); + if (!ringBearer.hasKeyword(Keyword.RING_BEARER)) + throw new DeckInvalidException("Assigned Ring-bearer can not bear the ring"); + + // Ring + if (deck.getRing() == null) + throw new DeckInvalidException("Deck doesn't have a Ring"); + LotroCardBlueprint ring = _library.getLotroCardBlueprint(deck.getRing()); + if (ring.getCardType() != CardType.THE_ONE_RING) + throw new DeckInvalidException("Assigned Ring is not The One Ring"); + + // Sites + if (deck.getSites() == null) + throw new DeckInvalidException("Deck doesn't have sites"); + if (deck.getSites().size() != 9) + throw new DeckInvalidException("Deck doesn't have exactly nine sites"); + for (String site : deck.getSites()) { + LotroCardBlueprint siteBlueprint = _library.getLotroCardBlueprint(site); + if (siteBlueprint.getCardType() != CardType.SITE) + throw new DeckInvalidException("Assigned Site is not really a site"); + } + + if (isOrderedSites()) { + boolean[] sites = new boolean[9]; + for (String site : deck.getSites()) { + LotroCardBlueprint blueprint = _library.getLotroCardBlueprint(site); + if (sites[blueprint.getSiteNumber() - 1]) + throw new DeckInvalidException("Deck has multiple of the same site number"); + sites[blueprint.getSiteNumber() - 1] = true; + } + } + + // Deck + if (deck.getAdventureCards().size() < _minimumDeckSize) + throw new DeckInvalidException("Deck contains below minimum number of cards"); + if (_validateShadowFPCount) { + int shadow = 0; + int fp = 0; + for (String blueprintId : deck.getAdventureCards()) { + LotroCardBlueprint card = _library.getLotroCardBlueprint(blueprintId); + if (card.getSide() == Side.SHADOW) + shadow++; + else if (card.getSide() == Side.FREE_PEOPLE) + fp++; + else + throw new DeckInvalidException("Deck contains non-shadow, non-free-people card"); + } + if (fp != shadow) + throw new DeckInvalidException("Deck contains different number of shadow and free people cards"); + } + + // Card count in deck and Ring-bearer + Map cardCountByName = new HashMap(); + cardCountByName.put(ringBearer.getName(), 1); + for (String blueprintId : deck.getAdventureCards()) { + LotroCardBlueprint cardBlueprint = _library.getLotroCardBlueprint(blueprintId); + increateCount(cardCountByName, cardBlueprint.getName()); + } + for (int count : cardCountByName.values()) { + if (count > _maximumSameName) + throw new DeckInvalidException("Deck contains more of the same card than allowed"); + } + + // Restricted cards + for (String name : _restrictedCard) { + Integer count = cardCountByName.get(name); + if (count != null && count > 1) + throw new DeckInvalidException("Deck contains more than one copy of a restricted card"); + } + + } catch (IllegalArgumentException exp) { + throw new DeckInvalidException("Deck contains unrecognizable card"); + } + } + + private void increateCount(Map counts, String name) { + Integer count = counts.get(name); + if (count == null) { + counts.put(name, 1); + } else { + counts.put(name, count + 1); + } + } +} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/formats/FotRBlockFormat.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/formats/FotRBlockFormat.java new file mode 100644 index 000000000..055f31895 --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/formats/FotRBlockFormat.java @@ -0,0 +1,15 @@ +package com.gempukku.lotro.game.formats; + +import com.gempukku.lotro.game.LotroCardBlueprintLibrary; + +public class FotRBlockFormat extends DefaultLotroFormat { + public FotRBlockFormat(LotroCardBlueprintLibrary library) { + super(library, true, 60, 4); + addRestrictedCard("Forces of Mordor"); + } + + @Override + public boolean isOrderedSites() { + return true; + } +} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/formats/LotroFormat.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/formats/LotroFormat.java new file mode 100644 index 000000000..adc8bba61 --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/formats/LotroFormat.java @@ -0,0 +1,10 @@ +package com.gempukku.lotro.game.formats; + +import com.gempukku.lotro.game.DeckInvalidException; +import com.gempukku.lotro.logic.vo.LotroDeck; + +public interface LotroFormat { + public boolean isOrderedSites(); + + public void validateDeck(LotroDeck deck) throws DeckInvalidException; +} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/formats/ModifiedFotRBlockFormat.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/formats/ModifiedFotRBlockFormat.java new file mode 100644 index 000000000..941ce40cf --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/formats/ModifiedFotRBlockFormat.java @@ -0,0 +1,14 @@ +package com.gempukku.lotro.game.formats; + +import com.gempukku.lotro.game.LotroCardBlueprintLibrary; + +public class ModifiedFotRBlockFormat extends DefaultLotroFormat { + public ModifiedFotRBlockFormat(LotroCardBlueprintLibrary library) { + super(library, false, 0, Integer.MAX_VALUE); + } + + @Override + public boolean isOrderedSites() { + return true; + } +} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/hall/AwaitingTable.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/hall/AwaitingTable.java index 477c4ca63..e7e03a3c8 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/hall/AwaitingTable.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/hall/AwaitingTable.java @@ -1,14 +1,22 @@ package com.gempukku.lotro.hall; import com.gempukku.lotro.game.LotroGameParticipant; +import com.gempukku.lotro.game.formats.LotroFormat; import java.util.*; public class AwaitingTable { + private String _formatName; + private LotroFormat _lotroFormat; private Map _players = new HashMap(); private int _capacity = 2; + public AwaitingTable(String formatName, LotroFormat lotroFormat) { + _formatName = formatName; + _lotroFormat = lotroFormat; + } + public boolean addPlayer(LotroGameParticipant player) { _players.put(player.getPlayerId(), player); return _players.size() == _capacity; @@ -30,4 +38,12 @@ public class AwaitingTable { public Set getPlayers() { return Collections.unmodifiableSet(new HashSet(_players.values())); } + + public String getFormatName() { + return _formatName; + } + + public LotroFormat getLotroFormat() { + return _lotroFormat; + } } 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 e1ca4581a..f77bd858a 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 @@ -2,7 +2,13 @@ package com.gempukku.lotro.hall; import com.gempukku.lotro.AbstractServer; import com.gempukku.lotro.chat.ChatServer; -import com.gempukku.lotro.game.*; +import com.gempukku.lotro.game.DeckInvalidException; +import com.gempukku.lotro.game.LotroGameMediator; +import com.gempukku.lotro.game.LotroGameParticipant; +import com.gempukku.lotro.game.LotroServer; +import com.gempukku.lotro.game.formats.FotRBlockFormat; +import com.gempukku.lotro.game.formats.LotroFormat; +import com.gempukku.lotro.game.formats.ModifiedFotRBlockFormat; import com.gempukku.lotro.logic.vo.LotroDeck; import java.util.*; @@ -12,7 +18,7 @@ public class HallServer extends AbstractServer { private ChatServer _chatServer; private LotroServer _lotroServer; - private LotroFormat _lotroFormat = new DefaultLotroFormat(true); + private Map _supportedFormats = new HashMap(); private Map _awaitingTables = new ConcurrentHashMap(); private Map _runningTables = Collections.synchronizedMap(new LinkedHashMap()); @@ -22,27 +28,39 @@ public class HallServer extends AbstractServer { private Map _lastVisitedPlayers = Collections.synchronizedMap(new LinkedHashMap()); - public HallServer(LotroServer lotroServer, ChatServer chatServer) { + public HallServer(LotroServer lotroServer, ChatServer chatServer, boolean test) { _lotroServer = lotroServer; _chatServer = chatServer; - _chatServer.createChatRoom("default"); + _chatServer.createChatRoom("Game Hall"); + + _supportedFormats.put("FotR block", new FotRBlockFormat(_lotroServer.getLotroCardBlueprintLibrary())); + if (test) + _supportedFormats.put("Modified FotR block", new ModifiedFotRBlockFormat(_lotroServer.getLotroCardBlueprintLibrary())); + } + + public Set getSupportedFormats() { + return new TreeSet(_supportedFormats.keySet()); } /** * @param playerId * @return If table created, otherwise false (if the user already is sitting at a table or playing). */ - public synchronized void createNewTable(String playerId) throws HallException { - LotroDeck lotroDeck = validateUserAndDeck(playerId); + public synchronized void createNewTable(String format, String playerId) throws HallException { + LotroFormat supportedFormat = _supportedFormats.get(format); + if (supportedFormat == null) + throw new HallException("This format is not supported: " + format); + + LotroDeck lotroDeck = validateUserAndDeck(supportedFormat, playerId); String tableId = String.valueOf(_nextTableId++); - AwaitingTable table = new AwaitingTable(); + AwaitingTable table = new AwaitingTable(format, supportedFormat); _awaitingTables.put(tableId, table); joinTableInternal(tableId, playerId, table, lotroDeck); } - private LotroDeck validateUserAndDeck(String playerId) throws HallException { + private LotroDeck validateUserAndDeck(LotroFormat format, String playerId) throws HallException { if (isPlayerBusy(playerId)) throw new HallException("You can't play more than one game at a time or wait at more than one table"); @@ -50,9 +68,11 @@ public class HallServer extends AbstractServer { if (lotroDeck == null) throw new HallException("You don't have a deck registered yet"); - boolean valid = _lotroFormat.validateDeck(lotroDeck); - if (!valid) - throw new HallException("Your registered deck is not valid for this format"); + try { + format.validateDeck(lotroDeck); + } catch (DeckInvalidException e) { + throw new HallException("Your registered deck is not valid for this format: " + e.getMessage()); + } return lotroDeck; } @@ -65,7 +85,7 @@ public class HallServer extends AbstractServer { if (awaitingTable == null) throw new HallException("Table is already taken or was removed"); - LotroDeck lotroDeck = validateUserAndDeck(playerId); + LotroDeck lotroDeck = validateUserAndDeck(awaitingTable.getLotroFormat(), playerId); joinTableInternal(tableId, playerId, awaitingTable, lotroDeck); @@ -77,7 +97,7 @@ public class HallServer extends AbstractServer { if (tableFull) { Set players = awaitingTable.getPlayers(); LotroGameParticipant[] participants = players.toArray(new LotroGameParticipant[players.size()]); - String gameId = _lotroServer.createNewGame(new DefaultLotroFormat(true), participants); + String gameId = _lotroServer.createNewGame(awaitingTable.getLotroFormat(), participants); LotroGameMediator lotroGameMediator = _lotroServer.getGameById(gameId); lotroGameMediator.startGame(); _runningTables.put(tableId, gameId); 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 aa6b81e97..b49b183e4 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 @@ -35,6 +35,7 @@ import java.util.Set; @Path("/") public class ServerResource { private static final Logger _logger = Logger.getLogger(ServerResource.class); + private boolean _test = true; private HallServer _hallServer; private LotroServer _lotroServer; @@ -50,7 +51,7 @@ public class ServerResource { _lotroServer = new LotroServer(_chatServer); _lotroServer.startServer(); - _hallServer = new HallServer(_lotroServer, _chatServer); + _hallServer = new HallServer(_lotroServer, _chatServer, _test); _hallServer.startServer(); } catch (RuntimeException exp) { _logger.error("Error while creating resource", exp); @@ -59,16 +60,6 @@ public class ServerResource { _logger.debug("Resource created"); } - private String createGameOnServer(String player1Name, String player2Name) { - LotroGameParticipant[] participants = new LotroGameParticipant[2]; - participants[0] = new LotroGameParticipant(player1Name, _lotroServer.getParticipantDeck(player1Name)); - participants[1] = new LotroGameParticipant(player2Name, _lotroServer.getParticipantDeck(player2Name)); - - String gameId = _lotroServer.createNewGame(new DefaultLotroFormat(true), participants); - _lotroServer.getGameById(gameId).startGame(); - return gameId; - } - @Path("/login") @POST public void login( @@ -82,41 +73,6 @@ public class ServerResource { logUser(request, login); } - @Path("/createGame") - @POST - @Produces(MediaType.TEXT_HTML) - public String createGame( - @FormParam("player1") String player1Name, - @FormParam("player2") String player2Name) { - PlayerDAO playerDao = _lotroServer.getPlayerDao(); - Player player1 = playerDao.getPlayer(player1Name); - if (player1 == null) - return "Error: Can't find user with name: " + player1Name; - Player player2 = playerDao.getPlayer(player2Name); - if (player2 == null) - return "Error: Can't find user with name: " + player2Name; - - if (player1Name.equals(player2Name)) - return "Error: Can't create game with two same players"; - - DeckDAO deckDao = _lotroServer.getDeckDao(); - Deck deck1 = deckDao.getDeckForPlayer(player1, "default"); - if (deck1 == null) - return "Error: Can't find deck for user with name: " + player1Name + " - create deck"; - Deck deck2 = deckDao.getDeckForPlayer(player2, "default"); - if (deck2 == null) - return "Error: Can't find deck for user with name: " + player2Name + " - create deck"; - - String gameId = createGameOnServer(player1Name, player2Name); - - return "Game created, open following links in two windows:
" + - "" + player1Name + "
" + - "" + player2Name + "
" + - "If you wish to edit decks, use following links:
" + - "" + player1Name + "
" + - "" + player2Name + ""; - } - @Path("/game/{gameId}") @GET @Produces(MediaType.APPLICATION_XML) @@ -124,16 +80,14 @@ public class ServerResource { @PathParam("gameId") String gameId, @QueryParam("participantId") String participantId, @Context HttpServletRequest request) throws ParserConfigurationException { -// String participantId = getLoggedUser(request); + if (!_test) + participantId = getLoggedUser(request); LotroGameMediator gameMediator = _lotroServer.getGameById(gameId); if (gameMediator == null) sendError(Response.Status.NOT_FOUND); - if (participantId == null) - sendError(Response.Status.NOT_FOUND); - DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document doc = documentBuilder.newDocument(); @@ -153,15 +107,13 @@ public class ServerResource { @QueryParam("cardId") int cardId, @QueryParam("participantId") String participantId, @Context HttpServletRequest request) throws ParserConfigurationException { -// String participantId = getLoggedUser(request); + if (!_test) + participantId = getLoggedUser(request); LotroGameMediator gameMediator = _lotroServer.getGameById(gameId); if (gameMediator == null) sendError(Response.Status.NOT_FOUND); - if (participantId == null) - sendError(Response.Status.NOT_FOUND); - return gameMediator.produceCardInfo(participantId, cardId); } @@ -174,7 +126,8 @@ public class ServerResource { @FormParam("decisionId") Integer decisionId, @FormParam("decisionValue") String decisionValue, @Context HttpServletRequest request) throws ParserConfigurationException { -// String participantId = getLoggedUser(request); + if (!_test) + participantId = getLoggedUser(request); long start = System.currentTimeMillis(); @@ -182,9 +135,6 @@ public class ServerResource { if (gameMediator == null) sendError(Response.Status.NOT_FOUND); - if (participantId == null) - sendError(Response.Status.NOT_FOUND); - if (decisionId != null) gameMediator.playerAnswered(participantId, decisionId, decisionValue); @@ -199,7 +149,7 @@ public class ServerResource { doc.appendChild(update); long time = System.currentTimeMillis() - start; - if (time > 10) + if (time > 100) _logger.debug("Processing time: " + time); return doc; @@ -212,6 +162,9 @@ public class ServerResource { @PathParam("deckType") String deckType, @QueryParam("participantId") String participantId, @Context HttpServletRequest request) throws ParserConfigurationException { + if (!_test) + participantId = getLoggedUser(request); + PlayerDAO playerDao = _lotroServer.getPlayerDao(); DeckDAO deckDao = _lotroServer.getDeckDao(); @@ -262,7 +215,10 @@ public class ServerResource { public Document createDeck( @PathParam("deckType") String deckType, @FormParam("participantId") String participantId, - @FormParam("deckContents") String contents) throws ParserConfigurationException { + @FormParam("deckContents") String contents, + @Context HttpServletRequest request) throws ParserConfigurationException { + if (!_test) + participantId = getLoggedUser(request); PlayerDAO playerDao = _lotroServer.getPlayerDao(); DeckDAO deckDao = _lotroServer.getDeckDao(); @@ -297,6 +253,9 @@ public class ServerResource { @QueryParam("start") int start, @QueryParam("count") int count, @Context HttpServletRequest request) throws ParserConfigurationException { + if (!_test) + participantId = getLoggedUser(request); + if (collectionType == null || !collectionType.equals("default")) sendError(Response.Status.NOT_FOUND); @@ -331,7 +290,11 @@ public class ServerResource { @Produces(MediaType.APPLICATION_XML) public Document getMessages( @PathParam("room") String room, - @QueryParam("participantId") String participantId) throws ParserConfigurationException { + @QueryParam("participantId") String participantId, + @Context HttpServletRequest request) throws ParserConfigurationException { + if (!_test) + participantId = getLoggedUser(request); + ChatRoomMediator chatRoom = _chatServer.getChatRoom(room); if (chatRoom == null) sendError(Response.Status.NOT_FOUND); @@ -355,7 +318,11 @@ public class ServerResource { public Document postMessage( @PathParam("room") String room, @FormParam("participantId") String participantId, - @FormParam("message") String message) throws ParserConfigurationException { + @FormParam("message") String message, + @Context HttpServletRequest request) throws ParserConfigurationException { + if (!_test) + participantId = getLoggedUser(request); + ChatRoomMediator chatRoom = _chatServer.getChatRoom(room); if (chatRoom == null) sendError(Response.Status.NOT_FOUND); @@ -383,7 +350,11 @@ public class ServerResource { @GET @Produces(MediaType.APPLICATION_XML) public Document getHall( - @QueryParam("participantId") String participantId) throws ParserConfigurationException { + @QueryParam("participantId") String participantId, + @Context HttpServletRequest request) throws ParserConfigurationException { + if (!_test) + participantId = getLoggedUser(request); + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); @@ -392,6 +363,11 @@ public class ServerResource { Element hall = doc.createElement("hall"); _hallServer.processTables(participantId, new SerializeHallInfoVisitor(doc, hall)); + for (String format : _hallServer.getSupportedFormats()) { + Element formatElem = doc.createElement("format"); + formatElem.appendChild(doc.createTextNode(format)); + hall.appendChild(formatElem); + } doc.appendChild(hall); @@ -402,7 +378,11 @@ public class ServerResource { @POST public Document joinTable( @PathParam("table") String tableId, - @FormParam("participantId") String participantId) throws ParserConfigurationException { + @FormParam("participantId") String participantId, + @Context HttpServletRequest request) throws ParserConfigurationException { + if (!_test) + participantId = getLoggedUser(request); + try { _hallServer.joinTableAsPlayer(tableId, participantId); return null; @@ -411,6 +391,34 @@ public class ServerResource { } } + @Path("/hall") + @POST + public Document createTable( + @FormParam("format") String format, + @FormParam("participantId") String participantId, + @Context HttpServletRequest request) throws ParserConfigurationException { + if (!_test) + participantId = getLoggedUser(request); + + try { + _hallServer.createNewTable(format, participantId); + return null; + } catch (HallException e) { + return marshalException(e); + } + } + + @Path("/hall/leave") + @POST + public void leaveTable( + @FormParam("participantId") String participantId, + @Context HttpServletRequest request) throws ParserConfigurationException { + if (!_test) + participantId = getLoggedUser(request); + + _hallServer.leaveAwaitingTables(participantId); + } + private Document marshalException(HallException e) throws ParserConfigurationException { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); @@ -423,25 +431,6 @@ public class ServerResource { return doc; } - @Path("/hall") - @POST - public Document createTable( - @FormParam("participantId") String participantId) throws ParserConfigurationException { - try { - _hallServer.createNewTable(participantId); - return null; - } catch (HallException e) { - return marshalException(e); - } - } - - @Path("/hall/leave") - @POST - public void leaveTable( - @FormParam("participantId") String participantId) throws ParserConfigurationException { - _hallServer.leaveAwaitingTables(participantId); - } - private class SerializeHallInfoVisitor implements HallInfoVisitor { private Document _doc; private Element _hall; @@ -623,7 +612,10 @@ public class ServerResource { } private String getLoggedUser(HttpServletRequest request) { - return (String) request.getSession().getAttribute("logged"); + String loggedUser = (String) request.getSession().getAttribute("logged"); + if (loggedUser == null) + sendError(Response.Status.UNAUTHORIZED); + return loggedUser; } private void sendError(Response.Status status) { diff --git a/gemp-lotr/gemp-lotr-web/src/main/webapp/index.html b/gemp-lotr/gemp-lotr-web/src/main/webapp/index.html index 2718aef8b..db4e100e9 100644 --- a/gemp-lotr/gemp-lotr-web/src/main/webapp/index.html +++ b/gemp-lotr/gemp-lotr-web/src/main/webapp/index.html @@ -78,7 +78,7 @@ $("#user").append("You may edit your deck.
"); $("#user").append("Create a table or join one where other player is waiting to start a game."); - var chat = new ChatBoxUI("default", $("#chat"), "/gemp-lotr/server", true); + var chat = new ChatBoxUI("Game Hall", $("#chat"), "/gemp-lotr/server", true); chat.setBounds(2, 2, 780 - 4, 200 - 4); var hall = new GempLotrHallUI($("#hall"), "/gemp-lotr/server", chat); diff --git a/gemp-lotr/gemp-lotr-web/src/main/webapp/js/communication.js b/gemp-lotr/gemp-lotr-web/src/main/webapp/js/communication.js index 01e79ba54..c35a15aff 100644 --- a/gemp-lotr/gemp-lotr-web/src/main/webapp/js/communication.js +++ b/gemp-lotr/gemp-lotr-web/src/main/webapp/js/communication.js @@ -156,12 +156,13 @@ var GempLotrCommunication = Class.extend({ dataType: "xml" }); }, - createTable: function(callback) { + createTable: function(format, callback) { $.ajax({ type: "POST", url: this.url + "/hall", cache: false, data: { + format: format, participantId: getUrlParam("participantId")}, success: callback, error: this.failure, diff --git a/gemp-lotr/gemp-lotr-web/src/main/webapp/js/hallUi.js b/gemp-lotr/gemp-lotr-web/src/main/webapp/js/hallUi.js index f98c2e910..73ff06a4a 100644 --- a/gemp-lotr/gemp-lotr-web/src/main/webapp/js/hallUi.js +++ b/gemp-lotr/gemp-lotr-web/src/main/webapp/js/hallUi.js @@ -1,6 +1,9 @@ var GempLotrHallUI = Class.extend({ div : null, comm: null, + chat: null, + supportedFormatsInitialized: false, + supportedFormatsSelect: null, createTableButton: null, leaveTableButton: null, @@ -9,9 +12,10 @@ var GempLotrHallUI = Class.extend({ init: function(div, url, chat) { this.div = div; this.comm = new GempLotrCommunication(url, function() { - chat.appendMessage("The game hall had a problem communication with the server, no new updates will be displayed.", "warningMessage"); + chat.appendMessage("The game hall had a problem communicating with the server, no new updates will be displayed.", "warningMessage"); chat.appendMessage("Reload the browser page (press F5) to resume the game hall functionality.", "warningMessage"); }); + this.chat = chat; var width = $(div).width(); var height = $(div).height(); @@ -25,16 +29,22 @@ var GempLotrHallUI = Class.extend({ var that = this; + this.supportedFormatsSelect = $(""); + this.supportedFormatsSelect.hide(); + this.createTableButton = $(""); $(this.createTableButton).button().click( function() { + that.supportedFormatsSelect.hide(); that.createTableButton.hide(); - that.comm.createTable(function(xml) { + var format = that.supportedFormatsSelect.val(); + that.comm.createTable(format, function(xml) { that.processResponse(xml); }); }); this.createTableButton.hide(); + buttonsDiv.append(this.supportedFormatsSelect); buttonsDiv.append(this.createTableButton); this.leaveTableButton = $(""); @@ -65,7 +75,7 @@ var GempLotrHallUI = Class.extend({ var root = xml.documentElement; if (root.tagName == "error") { var message = root.getAttribute("message"); - alert(message); + this.chat.appendMessage(message, "warningMessage"); } } }, @@ -101,10 +111,21 @@ var GempLotrHallUI = Class.extend({ location.href = "/gemp-lotr/game.html?gameId=" + waitingGameId + participantIdAppend; } + if (!this.supportedFormatsInitialized) { + var formats = root.getElementsByTagName("format"); + for (var i = 0; i < formats.length; i++) { + var format = formats[i].childNodes[0].nodeValue; + this.supportedFormatsSelect.append(""); + } + this.supportedFormatsInitialized = true; + } + if (waiting) { + this.supportedFormatsSelect.hide(); this.createTableButton.hide(); this.leaveTableButton.show(); } else { + this.supportedFormatsSelect.show(); this.createTableButton.show(); this.leaveTableButton.hide(); } diff --git a/gemp-lotr/todo.txt b/gemp-lotr/todo.txt index 9961bca55..4738c0108 100644 --- a/gemp-lotr/todo.txt +++ b/gemp-lotr/todo.txt @@ -1,6 +1,5 @@ TO DO: Before release: -28. Introduce deck validation for FotR block format. 29. Player registration and login. 31. Allow to cancel selection to reset to none-selected and go with different selection if no auto-accept is set or multiple choices required. @@ -46,3 +45,4 @@ with Filters.sameCard(...) filter. 20. Display "chess-clock" for each player. 15. Add join game screen, where players can choose to play and get paired automatically when a pair becomes available. 27. Show list of players in the hall. +28. Introduce deck validation for FotR block format.