Adding support for on-demand tournaments - client side.

This commit is contained in:
marcins78@gmail.com
2012-07-03 10:14:24 +00:00
parent 039f7893d7
commit 421848f07d
7 changed files with 171 additions and 19 deletions

View File

@@ -8,4 +8,6 @@ public interface HallInfoVisitor {
public void visitTable(String tableId, String gameId, boolean noSpectators, String tableStatus, String formatName, String tournamentName, Set<String> playerIds, String winner);
public void runningPlayerGame(String gameId);
public void visitTournamentQueue(String tournamentQueueKey, String collectionName, String formatName, String tournamentQueueName, int playerCount, boolean playerSignedUp);
}

View File

@@ -59,7 +59,7 @@ public class HallServer extends AbstractServer {
_collectionsManager = collectionsManager;
_hallChat = _chatServer.createChatRoom("Game Hall", 10);
_tournamentQueues.put("queue-1", new SingleEliminationTournamentQueue(_formatLibrary.getFormat("fotr_block"),
_tournamentQueues.put("fotr_queue", new SingleEliminationTournamentQueue(_formatLibrary.getFormat("fotr_block"),
new CollectionType("default", "All cards"), "fotrQueue-", 1, "Fellowship Block On-Demand", 4,
tournamentService));
}
@@ -204,6 +204,18 @@ public class HallServer extends AbstractServer {
}
}
public void leaveQueues(Player player) {
_hallDataAccessLock.writeLock().lock();
try {
for (TournamentQueue tournamentQueue : _tournamentQueues.values()) {
if (tournamentQueue.isPlayerSignedUp(player.getName()))
tournamentQueue.leavePlayer(player.getName());
}
} finally {
_hallDataAccessLock.writeLock().unlock();
}
}
public void leaveAwaitingTables(Player player) {
_hallDataAccessLock.writeLock().lock();
try {
@@ -220,7 +232,7 @@ public class HallServer extends AbstractServer {
}
}
public void processTables(Player player, HallInfoVisitor visitor) {
public void processHall(Player player, HallInfoVisitor visitor) {
_hallDataAccessLock.readLock().lock();
try {
_lastVisitedPlayers.put(player, System.currentTimeMillis());
@@ -255,6 +267,14 @@ public class HallServer extends AbstractServer {
visitor.visitTable(nonPlayingGame.getKey(), runningTable.getGameId(), lotroGameMediator.isNoSpectators(), lotroGameMediator.getGameStatus(), runningTable.getFormatName(), runningTable.getTournamentName(), lotroGameMediator.getPlayersPlaying(), lotroGameMediator.getWinner());
}
for (Map.Entry<String, TournamentQueue> tournamentQueueEntry : _tournamentQueues.entrySet()) {
String tournamentQueueKey = tournamentQueueEntry.getKey();
TournamentQueue tournamentQueue = tournamentQueueEntry.getValue();
visitor.visitTournamentQueue(tournamentQueueKey, tournamentQueue.getCollectionType().getFullName(),
tournamentQueue.getLotroFormat().getName(), tournamentQueue.getTournamentQueueName(),
tournamentQueue.getPlayerCount(), tournamentQueue.isPlayerSignedUp(player.getName()));
}
String gameId = getPlayingPlayerGameId(player.getName());
if (gameId != null)
visitor.runningPlayerGame(gameId);

View File

@@ -70,6 +70,11 @@ public class SingleEliminationTournamentQueue implements TournamentQueue {
_playerDecks.put(player, deck);
}
@Override
public synchronized int getPlayerCount() {
return _playerDecks.size();
}
@Override
public synchronized void leavePlayer(String player) {
_playerDecks.remove(player);

View File

@@ -17,5 +17,7 @@ public interface TournamentQueue {
public void leavePlayer(String player);
public int getPlayerCount();
public boolean isPlayerSignedUp(String player);
}

View File

@@ -129,7 +129,7 @@ public class HallResource extends AbstractResource {
if (motd != null)
hall.setAttribute("motd", motd);
_hallServer.processTables(resourceOwner, new SerializeHallInfoVisitor(doc, hall));
_hallServer.processHall(resourceOwner, new SerializeHallInfoVisitor(doc, hall));
for (Map.Entry<String, LotroFormat> format : _hallServer.getSupportedFormats().entrySet()) {
Element formatElem = doc.createElement("format");
formatElem.setAttribute("type", format.getKey());
@@ -154,6 +154,33 @@ public class HallResource extends AbstractResource {
return doc;
}
@Path("/queue/{queue}")
@POST
public Document joinQueue(
@PathParam("queue") String queueId,
@FormParam("deckName") String deckName,
@FormParam("participantId") String participantId,
@Context HttpServletRequest request) throws ParserConfigurationException {
Player resourceOwner = getResourceOwnerSafely(request, participantId);
try {
_hallServer.joinQueue(queueId, resourceOwner, deckName);
return null;
} catch (HallException e) {
return marshalException(e);
}
}
@Path("/queue/leave")
@POST
public void leaveQueue(
@FormParam("participantId") String participantId,
@Context HttpServletRequest request) throws ParserConfigurationException {
Player resourceOwner = getResourceOwnerSafely(request, participantId);
_hallServer.leaveQueues(resourceOwner);
}
@Path("/{table}")
@POST
public Document joinTable(
@@ -171,6 +198,16 @@ public class HallResource extends AbstractResource {
}
}
@Path("/leave")
@POST
public void leaveTable(
@FormParam("participantId") String participantId,
@Context HttpServletRequest request) throws ParserConfigurationException {
Player resourceOwner = getResourceOwnerSafely(request, participantId);
_hallServer.leaveAwaitingTables(resourceOwner);
}
@POST
public Document createTable(
@FormParam("format") String format,
@@ -187,16 +224,6 @@ public class HallResource extends AbstractResource {
}
}
@Path("/leave")
@POST
public void leaveTable(
@FormParam("participantId") String participantId,
@Context HttpServletRequest request) throws ParserConfigurationException {
Player resourceOwner = getResourceOwnerSafely(request, participantId);
_hallServer.leaveAwaitingTables(resourceOwner);
}
private Document marshalException(HallException e) throws ParserConfigurationException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
@@ -239,6 +266,18 @@ public class HallResource extends AbstractResource {
_hall.appendChild(table);
}
@Override
public void visitTournamentQueue(String tournamentQueueKey, String collectionName, String formatName,
String tournamentQueueName, int playerCount, boolean playerSignedUp) {
Element tournamentQueue = _doc.createElement("tournamentQueue");
tournamentQueue.setAttribute("id", tournamentQueueKey);
tournamentQueue.setAttribute("tournament", tournamentQueueName);
tournamentQueue.setAttribute("players", String.valueOf(playerCount));
tournamentQueue.setAttribute("format", formatName);
tournamentQueue.setAttribute("joined", String.valueOf(playerSignedUp));
_hall.appendChild(tournamentQueue);
}
@Override
public void runningPlayerGame(String gameId) {
Element runningGame = _doc.createElement("game");

View File

@@ -432,10 +432,10 @@ var GempLotrCommunication = Class.extend({
dataType:"xml"
});
},
joinTable:function (tableId, deckName, callback, errorMap) {
joinQueue:function (queueId, deckName, callback, errorMap) {
$.ajax({
type:"POST",
url:this.url + "/hall/" + tableId,
url:this.url + "/hall/queue/" + queueId,
cache:false,
data:{
deckName:deckName,
@@ -445,13 +445,23 @@ var GempLotrCommunication = Class.extend({
dataType:"xml"
});
},
createTable:function (format, deckName, callback, errorMap) {
leaveQueue:function (errorMap) {
$.ajax({
type:"POST",
url:this.url + "/hall",
url:this.url + "/hall/queue/leave",
cache:false,
data:{
participantId:getUrlParam("participantId")},
error:this.errorCheck(errorMap),
dataType:"xml"
});
},
joinTable:function (tableId, deckName, callback, errorMap) {
$.ajax({
type:"POST",
url:this.url + "/hall/" + tableId,
cache:false,
data:{
format:format,
deckName:deckName,
participantId:getUrlParam("participantId")},
success:this.deliveryCheck(callback),
@@ -470,6 +480,20 @@ var GempLotrCommunication = Class.extend({
dataType:"xml"
});
},
createTable:function (format, deckName, callback, errorMap) {
$.ajax({
type:"POST",
url:this.url + "/hall",
cache:false,
data:{
format:format,
deckName:deckName,
participantId:getUrlParam("participantId")},
success:this.deliveryCheck(callback),
error:this.errorCheck(errorMap),
dataType:"xml"
});
},
getFormat:function (formatCode, callback, errorMap) {
$.ajax({
type:"GET",

View File

@@ -11,6 +11,8 @@ var GempLotrHallUI = Class.extend({
tablesDiv:null,
buttonsDiv:null,
showEmptyTableQueues:null,
pocketDiv:null,
init:function (div, url, chat) {
@@ -88,9 +90,12 @@ var GempLotrHallUI = Class.extend({
this.decksSelect = $("<select style='width: 220px'></select>");
this.decksSelect.hide();
var showQueuesCheck = $("<label for='showEmptyTableQueuesCheck'>Show all queues</label><input type='checkbox' id='showEmptyTableQueuesCheck' value='showQueues'/>");
this.buttonsDiv.append(this.supportedFormatsSelect);
this.buttonsDiv.append(this.decksSelect);
this.buttonsDiv.append(this.createTableButton);
this.buttonsDiv.append(showQueuesCheck);
this.leaveTableButton = $("<button>Leave table</button>");
$(this.leaveTableButton).button().click(
@@ -169,10 +174,22 @@ var GempLotrHallUI = Class.extend({
var waiting = root.getAttribute("waiting") == "true";
var tables = root.getElementsByTagName("table");
var tablesTable = $("<table class='tables'></table>");
tablesTable.append("<tr><th width='20%'>Format</th><th width='30%'>Tournament</th><th width='10%'>Status</th><th width='20%'>Players</th><th width='20%'>Actions</th></tr>");
var tournamentQueues = root.getElementsByTagName("tournamentQueue");
for (var i = 0; i < tournamentQueues.length; i++) {
var tournamentQueue = tournamentQueues[i];
var id = tournamentQueue.getAttribute("id");
var tournamentName = tournamentQueue.getAttribute("tournament");
var players = parseInt(table.getAttribute("players"));
var formatName = table.getAttribute("format");
var joined = table.getAttribute("joined");
if (players > 0 || $("#showEmptyTableQueuesCheck").prop("checked"))
this.appendTournamentQueue(tablesTable, id, formatName, tournamentName, players, joined);
}
var tables = root.getElementsByTagName("table");
for (var i = 0; i < tables.length; i++) {
var table = tables[i];
var id = table.getAttribute("id");
@@ -234,6 +251,49 @@ var GempLotrHallUI = Class.extend({
}
},
appendTournamentQueue:function (container, id, formatName, tournamentName, players, joined) {
var row = $("<tr></tr>");
row.append("<td>" + formatName + "</td>");
row.append("<td>" + tournamentName + "</td>");
row.append("<td>" + "Accepting players" + "</td>");
row.append("<td>" + players + "</td>");
var actionsField = $("<td></td>");
if (players.length < 2) {
var that = this;
if (!joined) {
var but = $("<button>Join queue</button>");
$(but).button().click(
function (event) {
var deck = that.decksSelect.val();
if (deck != null)
that.comm.joinQueue(id, deck, function (xml) {
that.processResponse(xml);
});
});
actionsField.append(but);
} else {
var but = $("<button>Leave queue</button>");
$(but).button().click(
function (event) {
var deck = that.decksSelect.val();
if (deck != null)
that.comm.leaveQueue(id, deck, function (xml) {
that.processResponse(xml);
});
});
actionsField.append(but);
}
}
row.append(actionsField);
container.append(row);
},
appendTable:function (container, id, gameId, status, formatName, tournamentName, players, waiting, winner) {
var row = $("<tr></tr>");