Adding support for on-demand tournaments - client side.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -17,5 +17,7 @@ public interface TournamentQueue {
|
||||
|
||||
public void leavePlayer(String player);
|
||||
|
||||
public int getPlayerCount();
|
||||
|
||||
public boolean isPlayerSignedUp(String player);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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>");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user