Introducing format types and deck validation for formats. Also introduced test parameters in the ServerResource to be able to switch to test/non-test APIs.

This commit is contained in:
marcins78@gmail.com
2011-09-17 16:49:34 +00:00
parent b7d0093f28
commit fe12db4bfb
18 changed files with 331 additions and 135 deletions

View File

@@ -8,7 +8,6 @@ public class ChatRoom {
private Map<String, ChatRoomListener> _chatRoomListeners = new HashMap<String, ChatRoomListener>();
public ChatRoom() {
postMessage("System", "Welcome to the room");
}
public void postMessage(String from, String message) {

View File

@@ -9,7 +9,9 @@ public class ChatServer extends AbstractServer {
private Map<String, ChatRoomMediator> _chatRooms = new ConcurrentHashMap<String, ChatRoomMediator>();
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) {

View File

@@ -0,0 +1,7 @@
package com.gempukku.lotro.game;
public class DeckInvalidException extends Exception {
public DeckInvalidException(String message) {
super(message);
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -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<String> _restrictedCard = new HashSet<String>();
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<String, Integer> cardCountByName = new HashMap<String, Integer>();
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<String, Integer> counts, String name) {
Integer count = counts.get(name);
if (count == null) {
counts.put(name, 1);
} else {
counts.put(name, count + 1);
}
}
}

View File

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

View File

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

View File

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

View File

@@ -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<String, LotroGameParticipant> _players = new HashMap<String, LotroGameParticipant>();
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<LotroGameParticipant> getPlayers() {
return Collections.unmodifiableSet(new HashSet<LotroGameParticipant>(_players.values()));
}
public String getFormatName() {
return _formatName;
}
public LotroFormat getLotroFormat() {
return _lotroFormat;
}
}

View File

@@ -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<String, LotroFormat> _supportedFormats = new HashMap<String, LotroFormat>();
private Map<String, AwaitingTable> _awaitingTables = new ConcurrentHashMap<String, AwaitingTable>();
private Map<String, String> _runningTables = Collections.synchronizedMap(new LinkedHashMap<String, String>());
@@ -22,27 +28,39 @@ public class HallServer extends AbstractServer {
private Map<String, Long> _lastVisitedPlayers = Collections.synchronizedMap(new LinkedHashMap<String, Long>());
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<String> getSupportedFormats() {
return new TreeSet<String>(_supportedFormats.keySet());
}
/**
* @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 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<LotroGameParticipant> 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);

View File

@@ -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 "<b>Error:</b> Can't find user with name: " + player1Name;
Player player2 = playerDao.getPlayer(player2Name);
if (player2 == null)
return "<b>Error:</b> Can't find user with name: " + player2Name;
if (player1Name.equals(player2Name))
return "<b>Error:</b> Can't create game with two same players";
DeckDAO deckDao = _lotroServer.getDeckDao();
Deck deck1 = deckDao.getDeckForPlayer(player1, "default");
if (deck1 == null)
return "<b>Error:</b> Can't find deck for user with name: " + player1Name + " - <a href='deckBuild.html?participantId=" + player1Name + "'>create deck</a>";
Deck deck2 = deckDao.getDeckForPlayer(player2, "default");
if (deck2 == null)
return "<b>Error:</b> Can't find deck for user with name: " + player2Name + " - <a href='deckBuild.html?participantId=" + player2Name + "'>create deck</a>";
String gameId = createGameOnServer(player1Name, player2Name);
return "Game created, open following links in two windows:<br />" +
"<a href='game.html?gameId=" + gameId + "&participantId=" + player1Name + "'>" + player1Name + "</a><br />" +
"<a href='game.html?gameId=" + gameId + "&participantId=" + player2Name + "'>" + player2Name + "</a><br />" +
"If you wish to edit decks, use following links:<br />" +
"<a href='deckBuild.html?participantId=" + player1Name + "'>" + player1Name + "</a><br />" +
"<a href='deckBuild.html?participantId=" + player2Name + "'>" + player2Name + "</a>";
}
@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) {

View File

@@ -78,7 +78,7 @@
$("#user").append("You may <a href='deckBuild.html?participantId=" + participantId + "'>edit your deck</a>.<br/>");
$("#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);

View File

@@ -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,

View File

@@ -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 = $("<select></select>");
this.supportedFormatsSelect.hide();
this.createTableButton = $("<button>Create table</button>");
$(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 = $("<button>Leave table</button>");
@@ -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("<option value='" + format + "'>" + format + "</option>");
}
this.supportedFormatsInitialized = true;
}
if (waiting) {
this.supportedFormatsSelect.hide();
this.createTableButton.hide();
this.leaveTableButton.show();
} else {
this.supportedFormatsSelect.show();
this.createTableButton.show();
this.leaveTableButton.hide();
}

View File

@@ -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.