Deck builder now displays stats of the deck - shadow/FP card count and if the deck is valid for supported formats.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package com.gempukku.lotro.db;
|
||||
|
||||
import com.gempukku.lotro.db.vo.Deck;
|
||||
import com.gempukku.lotro.db.vo.Player;
|
||||
import com.gempukku.lotro.logic.vo.LotroDeck;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
@@ -15,25 +15,25 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
public class DeckDAO {
|
||||
private DbAccess _dbAccess;
|
||||
|
||||
private Map<Integer, Map<String, Deck>> _decks = new ConcurrentHashMap<Integer, Map<String, Deck>>();
|
||||
private Map<Integer, Map<String, LotroDeck>> _decks = new ConcurrentHashMap<Integer, Map<String, LotroDeck>>();
|
||||
|
||||
public DeckDAO(DbAccess dbAccess) {
|
||||
_dbAccess = dbAccess;
|
||||
}
|
||||
|
||||
public Deck getDeckForPlayer(Player player, String type) {
|
||||
Map<String, Deck> playerDecks = _decks.get(player.getId());
|
||||
public LotroDeck getDeckForPlayer(Player player, String type) {
|
||||
Map<String, LotroDeck> playerDecks = _decks.get(player.getId());
|
||||
if (playerDecks != null) {
|
||||
Deck deck = playerDecks.get(type);
|
||||
LotroDeck deck = playerDecks.get(type);
|
||||
if (deck != null)
|
||||
return deck;
|
||||
}
|
||||
|
||||
Deck deck = getDeckFromDB(player.getId(), type);
|
||||
LotroDeck deck = getDeckFromDB(player.getId(), type);
|
||||
if (deck != null) {
|
||||
Map<String, Deck> decksByType = _decks.get(player.getId());
|
||||
Map<String, LotroDeck> decksByType = _decks.get(player.getId());
|
||||
if (decksByType == null) {
|
||||
decksByType = new ConcurrentHashMap<String, Deck>();
|
||||
decksByType = new ConcurrentHashMap<String, LotroDeck>();
|
||||
_decks.put(player.getId(), decksByType);
|
||||
}
|
||||
decksByType.put(type, deck);
|
||||
@@ -42,22 +42,22 @@ public class DeckDAO {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setDeckForPlayer(Player player, String type, Deck deck) {
|
||||
public void setDeckForPlayer(Player player, String type, LotroDeck deck) {
|
||||
storeDeckToDB(player.getId(), type, deck);
|
||||
Map<String, Deck> decksByType = _decks.get(player.getId());
|
||||
Map<String, LotroDeck> decksByType = _decks.get(player.getId());
|
||||
if (decksByType == null) {
|
||||
decksByType = new ConcurrentHashMap<String, Deck>();
|
||||
decksByType = new ConcurrentHashMap<String, LotroDeck>();
|
||||
_decks.put(player.getId(), decksByType);
|
||||
}
|
||||
decksByType.put(type, deck);
|
||||
}
|
||||
|
||||
private void storeDeckToDB(int playerId, String type, Deck deck) {
|
||||
private void storeDeckToDB(int playerId, String type, LotroDeck deck) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(deck.getRingBearer());
|
||||
sb.append(",").append(deck.getRing());
|
||||
appendList(sb, deck.getSites());
|
||||
appendList(sb, deck.getDeck());
|
||||
appendList(sb, deck.getAdventureCards());
|
||||
|
||||
String contents = sb.toString();
|
||||
try {
|
||||
@@ -73,7 +73,7 @@ public class DeckDAO {
|
||||
sb.append("," + card);
|
||||
}
|
||||
|
||||
private Deck getDeckFromDB(int playerId, String type) {
|
||||
private LotroDeck getDeckFromDB(int playerId, String type) {
|
||||
try {
|
||||
String contents = getDeckContentsFromDB(playerId, type);
|
||||
if (contents != null) {
|
||||
@@ -86,9 +86,16 @@ public class DeckDAO {
|
||||
}
|
||||
}
|
||||
|
||||
private Deck buildDeckFromContents(String contents) {
|
||||
private LotroDeck buildDeckFromContents(String contents) {
|
||||
List<String> cardsList = Arrays.asList(contents.split(","));
|
||||
return new Deck(cardsList.get(0), cardsList.get(1), cardsList.subList(2, 11), cardsList.subList(11, cardsList.size()));
|
||||
LotroDeck deck = new LotroDeck();
|
||||
deck.setRingBearer(cardsList.get(0));
|
||||
deck.setRing(cardsList.get(1));
|
||||
for (int i = 2; i < 11; i++)
|
||||
deck.addSite(cardsList.get(i));
|
||||
for (int i = 11; i < cardsList.size(); i++)
|
||||
deck.addCard(cardsList.get(i));
|
||||
return deck;
|
||||
}
|
||||
|
||||
private void deleteDeckFromDB(int playerId, String type) throws SQLException {
|
||||
|
||||
@@ -7,7 +7,6 @@ import com.gempukku.lotro.common.Keyword;
|
||||
import com.gempukku.lotro.db.DbAccess;
|
||||
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;
|
||||
@@ -124,7 +123,7 @@ public class LotroServer extends AbstractServer {
|
||||
return gameId;
|
||||
}
|
||||
|
||||
public Deck validateDeck(String contents) {
|
||||
public LotroDeck validateDeck(String contents) {
|
||||
List<String> cards = Arrays.asList(contents.split(","));
|
||||
if (cards.size() < 11)
|
||||
return null;
|
||||
@@ -149,7 +148,14 @@ public class LotroServer extends AbstractServer {
|
||||
for (String card : cards.subList(11, cards.size()))
|
||||
_lotroCardBlueprintLibrary.getLotroCardBlueprint(card);
|
||||
|
||||
return new Deck(ringBearer, ring, cards.subList(2, 11), cards.subList(11, cards.size()));
|
||||
LotroDeck deck = new LotroDeck();
|
||||
deck.setRingBearer(cards.get(0));
|
||||
deck.setRing(cards.get(1));
|
||||
for (int i = 2; i < 11; i++)
|
||||
deck.addSite(cards.get(i));
|
||||
for (int i = 11; i < cards.size(); i++)
|
||||
deck.addCard(cards.get(i));
|
||||
return deck;
|
||||
} catch (IllegalArgumentException exp) {
|
||||
return null;
|
||||
}
|
||||
@@ -157,7 +163,7 @@ public class LotroServer extends AbstractServer {
|
||||
|
||||
public LotroDeck getParticipantDeck(String participantId) {
|
||||
Player player = _playerDao.getPlayer(participantId);
|
||||
Deck deck = _deckDao.getDeckForPlayer(player, "default");
|
||||
LotroDeck deck = _deckDao.getDeckForPlayer(player, "default");
|
||||
if (deck == null)
|
||||
return null;
|
||||
|
||||
@@ -166,7 +172,7 @@ public class LotroServer extends AbstractServer {
|
||||
lotroDeck.setRingBearer(deck.getRingBearer());
|
||||
for (String site : deck.getSites())
|
||||
lotroDeck.addSite(site);
|
||||
for (String card : deck.getDeck())
|
||||
for (String card : deck.getAdventureCards())
|
||||
lotroDeck.addCard(card);
|
||||
|
||||
return lotroDeck;
|
||||
|
||||
@@ -42,8 +42,8 @@ public class HallServer extends AbstractServer {
|
||||
return _awaitingTables.size() + _runningTables.size();
|
||||
}
|
||||
|
||||
public Set<String> getSupportedFormats() {
|
||||
return new TreeSet<String>(_supportedFormats.keySet());
|
||||
public Map<String, LotroFormat> getSupportedFormats() {
|
||||
return new TreeMap<String, LotroFormat>(_supportedFormats);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,15 +3,17 @@ package com.gempukku.lotro.server;
|
||||
import com.gempukku.lotro.chat.ChatMessage;
|
||||
import com.gempukku.lotro.chat.ChatRoomMediator;
|
||||
import com.gempukku.lotro.chat.ChatServer;
|
||||
import com.gempukku.lotro.common.Side;
|
||||
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.*;
|
||||
import com.gempukku.lotro.game.formats.LotroFormat;
|
||||
import com.gempukku.lotro.hall.HallException;
|
||||
import com.gempukku.lotro.hall.HallInfoVisitor;
|
||||
import com.gempukku.lotro.hall.HallServer;
|
||||
import com.gempukku.lotro.logic.decisions.AwaitingDecision;
|
||||
import com.gempukku.lotro.logic.vo.LotroDeck;
|
||||
import com.sun.jersey.spi.resource.Singleton;
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
@@ -204,7 +206,7 @@ public class ServerResource {
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
|
||||
Deck deck = deckDao.getDeckForPlayer(player, deckType);
|
||||
LotroDeck deck = deckDao.getDeckForPlayer(player, deckType);
|
||||
if (deck == null) {
|
||||
Document doc = documentBuilder.newDocument();
|
||||
Element deckElem = doc.createElement("deck");
|
||||
@@ -229,7 +231,7 @@ public class ServerResource {
|
||||
site.setAttribute("blueprintId", s);
|
||||
deckElem.appendChild(site);
|
||||
}
|
||||
for (String s : deck.getDeck()) {
|
||||
for (String s : deck.getAdventureCards()) {
|
||||
Element card = doc.createElement("card");
|
||||
card.setAttribute("blueprintId", s);
|
||||
deckElem.appendChild(card);
|
||||
@@ -256,7 +258,7 @@ public class ServerResource {
|
||||
if (player == null)
|
||||
sendError(Response.Status.UNAUTHORIZED);
|
||||
|
||||
Deck deck = _lotroServer.validateDeck(contents);
|
||||
LotroDeck deck = _lotroServer.validateDeck(contents);
|
||||
if (deck == null)
|
||||
sendError(Response.Status.BAD_REQUEST);
|
||||
|
||||
@@ -272,6 +274,48 @@ public class ServerResource {
|
||||
return doc;
|
||||
}
|
||||
|
||||
@Path("/deck")
|
||||
@POST
|
||||
@Produces("text/html")
|
||||
public String getDeckStats(
|
||||
@FormParam("participantId") String participantId,
|
||||
@FormParam("deckContents") String contents,
|
||||
@Context HttpServletRequest request) {
|
||||
if (!_test)
|
||||
participantId = getLoggedUser(request);
|
||||
|
||||
LotroDeck deck = _lotroServer.validateDeck(contents);
|
||||
if (deck == null)
|
||||
sendError(Response.Status.BAD_REQUEST);
|
||||
|
||||
int fpCount = 0;
|
||||
int shadowCount = 0;
|
||||
LotroCardBlueprintLibrary library = _lotroServer.getLotroCardBlueprintLibrary();
|
||||
for (String card : deck.getAdventureCards()) {
|
||||
Side side = library.getLotroCardBlueprint(card).getSide();
|
||||
if (side == Side.SHADOW)
|
||||
shadowCount++;
|
||||
else if (side == Side.FREE_PEOPLE)
|
||||
fpCount++;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<b>Free People</b>: " + fpCount + ", <b>Shadow</b>: " + shadowCount + "<br/>");
|
||||
|
||||
for (Map.Entry<String, LotroFormat> supportedFormats : _hallServer.getSupportedFormats().entrySet()) {
|
||||
String formatName = supportedFormats.getKey();
|
||||
LotroFormat format = supportedFormats.getValue();
|
||||
try {
|
||||
format.validateDeck(deck);
|
||||
sb.append("<b>" + formatName + "</b>: <font color='green'>valid</font> ");
|
||||
} catch (DeckInvalidException exp) {
|
||||
sb.append("<b>" + formatName + "</b>: <font color='red'>" + exp.getMessage() + "</font> ");
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Path("/collection/{collectionType}")
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_XML)
|
||||
@@ -392,7 +436,7 @@ public class ServerResource {
|
||||
Element hall = doc.createElement("hall");
|
||||
|
||||
_hallServer.processTables(participantId, new SerializeHallInfoVisitor(doc, hall));
|
||||
for (String format : _hallServer.getSupportedFormats()) {
|
||||
for (String format : _hallServer.getSupportedFormats().keySet()) {
|
||||
Element formatElem = doc.createElement("format");
|
||||
formatElem.appendChild(doc.createTextNode(format));
|
||||
hall.appendChild(formatElem);
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
#deckStats {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="css/dark-hive/jquery-ui-1.8.16.custom.css">
|
||||
<link rel="stylesheet" type="text/css" href="js/jquery/styles/jquery.spinnercontrol.css">
|
||||
|
||||
@@ -95,6 +95,19 @@ var GempLotrCommunication = Class.extend({
|
||||
dataType: "xml"
|
||||
});
|
||||
},
|
||||
getDeckStats: function(contents, callback) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: this.url + "/deck",
|
||||
cache: false,
|
||||
data: {
|
||||
participantId: getUrlParam("participantId"),
|
||||
deckContents: contents},
|
||||
success: callback,
|
||||
error: this.failure,
|
||||
dataType: "html"
|
||||
});
|
||||
},
|
||||
startChat: function(room, callback) {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
|
||||
@@ -176,6 +176,7 @@ var GempLotrDeckBuildingUI = Class.extend({
|
||||
|
||||
this.bottomBarDiv = $("<div></div>");
|
||||
this.bottomBarDiv.append("<button id='saveDeck' style='float: right;'>Save deck</button>");
|
||||
this.bottomBarDiv.append("<div id='deckStats'></div>")
|
||||
this.deckDiv.append(this.bottomBarDiv);
|
||||
$("#saveDeck").button().click(
|
||||
function() {
|
||||
@@ -197,8 +198,10 @@ var GempLotrDeckBuildingUI = Class.extend({
|
||||
that.displayCardInfo(selectedCardElem.data("card"));
|
||||
} else if (selectedCardElem.hasClass("cardInCollection")) {
|
||||
that.selectionFunc(selectedCardElem.data("card").blueprintId);
|
||||
that.updateDeckStats();
|
||||
} else if (selectedCardElem.hasClass("cardInDeck")) {
|
||||
that.removeCardFromDeck(selectedCardElem);
|
||||
that.updateDeckStats();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -242,7 +245,7 @@ var GempLotrDeckBuildingUI = Class.extend({
|
||||
this.infoDialog.dialog("open");
|
||||
},
|
||||
|
||||
saveDeck: function() {
|
||||
getDeckContents: function() {
|
||||
var ringBearer = $(".card", this.ringBearerDiv);
|
||||
var ring = $(".card", this.ringDiv);
|
||||
var site1 = $(".card", this.siteDivs[0]);
|
||||
@@ -257,7 +260,7 @@ var GempLotrDeckBuildingUI = Class.extend({
|
||||
|
||||
if (ringBearer.length == 0 || ring.length == 0 || site1.length == 0 || site2.length == 0 || site3.length == 0 || site4.length == 0
|
||||
|| site5.length == 0 || site6.length == 0 || site7.length == 0 || site8.length == 0 || site9.length == 0) {
|
||||
alert("To save a deck, it must have at least a Ring-Bearer, Ring and all 9 sites set");
|
||||
return null;
|
||||
} else {
|
||||
var cards = new Array();
|
||||
cards.push(ringBearer.data("card").blueprintId);
|
||||
@@ -277,10 +280,18 @@ var GempLotrDeckBuildingUI = Class.extend({
|
||||
cards.push($(this).data("card").blueprintId);
|
||||
});
|
||||
|
||||
this.comm.saveDeck("default", "" + cards, function(xml) {
|
||||
return "" + cards;
|
||||
}
|
||||
},
|
||||
|
||||
saveDeck: function() {
|
||||
var deckContents = this.getDeckContents();
|
||||
if (deckContents == null)
|
||||
alert("Deck must contain at least Ring-bearer, The One Ring and 9 sites");
|
||||
else
|
||||
this.comm.saveDeck("default", deckContents, function(xml) {
|
||||
alert("Deck was saved");
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
addCardToContainer: function(blueprintId, zone, container) {
|
||||
@@ -350,6 +361,15 @@ var GempLotrDeckBuildingUI = Class.extend({
|
||||
}
|
||||
},
|
||||
|
||||
updateDeckStats: function() {
|
||||
var deckContents = this.getDeckContents();
|
||||
if (deckContents != null)
|
||||
this.comm.getDeckStats(deckContents,
|
||||
function(html) {
|
||||
$("#deckStats").html(html);
|
||||
});
|
||||
},
|
||||
|
||||
removeCardFromDeck: function(cardDiv) {
|
||||
var cardData = cardDiv.data("card");
|
||||
if (cardData.attachedCards.length > 0) {
|
||||
@@ -386,6 +406,8 @@ var GempLotrDeckBuildingUI = Class.extend({
|
||||
this.layoutUI();
|
||||
}
|
||||
|
||||
this.updateDeckStats();
|
||||
|
||||
this.getCollection();
|
||||
}
|
||||
},
|
||||
@@ -452,7 +474,7 @@ var GempLotrDeckBuildingUI = Class.extend({
|
||||
this.drawDeckDiv.css({ position: "absolute", left: padding * 3 + sitesWidth * 2, top: padding, width: deckWidth - (sitesWidth + padding) * 2 - padding, height: deckHeight - 2 * padding - 50 });
|
||||
this.drawDeckGroup.setBounds(0, 0, deckWidth - (sitesWidth + padding) * 2 - padding, deckHeight - 2 * padding - 50);
|
||||
|
||||
this.bottomBarDiv.css({ position: "absolute", left: sitesWidth * 2, top: deckHeight - 50, width: deckWidth - sitesWidth * 2, height: 50 });
|
||||
this.bottomBarDiv.css({ position: "absolute", left: padding * 3 + sitesWidth * 2, top: deckHeight - 50, width: deckWidth - (sitesWidth + padding) * 2 - padding, height: 50 });
|
||||
|
||||
this.filterDiv.css({ position: "absolute", left: padding, top: 50, width: collectionWidth - padding, height: 50 });
|
||||
this.normalCollectionDiv.css({ position: "absolute", left: padding, top: 100, width: collectionWidth - padding * 2, height: collectionHeight - 100 });
|
||||
|
||||
Reference in New Issue
Block a user