From 9f0e645cd997de092c329c51c410fc07da7a3c1c Mon Sep 17 00:00:00 2001 From: "marcin.sciesinski" Date: Fri, 13 Apr 2018 08:53:48 -0700 Subject: [PATCH] Handling card picks in solo drafts --- .../async/handler/DraftRequestHandler.java | 199 ++++++++++++++++++ .../async/handler/LeagueRequestHandler.java | 2 +- .../lotro/collection/CollectionsManager.java | 12 +- .../lotro/league/ConstructedLeagueData.java | 2 +- .../com/gempukku/lotro/league/LeagueData.java | 2 +- .../league/NewConstructedLeagueData.java | 2 +- .../lotro/league/NewSealedLeagueData.java | 2 +- .../lotro/league/SealedLeagueData.java | 2 +- ...agueData.java => SoloDraftLeagueData.java} | 22 +- 9 files changed, 232 insertions(+), 13 deletions(-) create mode 100644 gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/DraftRequestHandler.java rename gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/{DraftLeagueData.java => SoloDraftLeagueData.java} (89%) diff --git a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/DraftRequestHandler.java b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/DraftRequestHandler.java new file mode 100644 index 000000000..d42e23230 --- /dev/null +++ b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/DraftRequestHandler.java @@ -0,0 +1,199 @@ +package com.gempukku.lotro.async.handler; + +import com.gempukku.lotro.async.ResponseWriter; +import com.gempukku.lotro.cards.CardSets; +import com.gempukku.lotro.collection.CollectionsManager; +import com.gempukku.lotro.db.vo.CollectionType; +import com.gempukku.lotro.db.vo.League; +import com.gempukku.lotro.draft2.SoloDraft; +import com.gempukku.lotro.draft2.SoloDraftDefinitions; +import com.gempukku.lotro.game.CardCollection; +import com.gempukku.lotro.game.Player; +import com.gempukku.lotro.league.LeagueData; +import com.gempukku.lotro.league.LeagueService; +import com.gempukku.lotro.league.SoloDraftLeagueData; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.handler.codec.http.HttpMethod; +import org.jboss.netty.handler.codec.http.HttpRequest; +import org.jboss.netty.handler.codec.http.QueryStringDecoder; +import org.jboss.netty.handler.codec.http.multipart.HttpPostRequestDecoder; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; + +public class DraftRequestHandler extends LotroServerRequestHandler implements UriRequestHandler { + private CollectionsManager _collectionsManager; + private SoloDraftDefinitions _soloDraftDefinitions; + private CardSets _cardSets; + private LeagueService _leagueService; + + public DraftRequestHandler(Map context) { + super(context); + _leagueService = extractObject(context, LeagueService.class); + _cardSets = extractObject(context, CardSets.class); + _soloDraftDefinitions = extractObject(context, SoloDraftDefinitions.class); + _collectionsManager = extractObject(context, CollectionsManager.class); + } + + @Override + public void handleRequest(String uri, HttpRequest request, Map context, ResponseWriter responseWriter, MessageEvent e) throws Exception { + if (uri.startsWith("/") && request.getMethod() == HttpMethod.POST) { + makePick(request, uri.substring(1), responseWriter); + } else if (uri.startsWith("/") && request.getMethod() == HttpMethod.GET) { + getAvailablePicks(request, uri.substring(1), responseWriter); + } else { + responseWriter.writeError(404); + } + } + + private void getAvailablePicks(HttpRequest request, String leagueType, ResponseWriter responseWriter) throws Exception { + QueryStringDecoder queryDecoder = new QueryStringDecoder(request.getUri()); + String participantId = getQueryParameterSafely(queryDecoder, "participantId"); + + League league = findLeagueByType(leagueType); + + if (league == null) + responseWriter.writeError(404); + + LeagueData leagueData = league.getLeagueData(_cardSets, _soloDraftDefinitions); + if (!leagueData.isSoloDraftLeague()) + responseWriter.writeError(404); + + SoloDraftLeagueData soloDraftLeagueData = (SoloDraftLeagueData) leagueData; + CollectionType collectionType = soloDraftLeagueData.getCollectionType(); + + Player resourceOwner = getResourceOwnerSafely(request, participantId); + + CardCollection collection = _collectionsManager.getPlayerCollection(resourceOwner, collectionType.getCode()); + boolean finished = (Boolean) collection.getExtraInformation().get("finished"); + if (finished) + responseWriter.writeError(404); + + int stage = ((Number) collection.getExtraInformation().get("stage")).intValue(); + long playerSeed = ((Number) collection.getExtraInformation().get("seed")).longValue(); + + SoloDraft soloDraft = soloDraftLeagueData.getSoloDraft(); + Iterable availableChoices = soloDraft.getAvailableChoices(playerSeed, stage); + + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + + Document doc = documentBuilder.newDocument(); + + Element availablePicksElem = doc.createElement("availablePicks"); + doc.appendChild(availablePicksElem); + + for (SoloDraft.DraftChoice availableChoice : availableChoices) { + String choiceId = availableChoice.getChoiceId(); + String blueprintId = availableChoice.getBlueprintId(); + String choiceUrl = availableChoice.getChoiceUrl(); + Element availablePick = doc.createElement("availablePick"); + availablePick.setAttribute("id", choiceId); + if (blueprintId != null) + availablePick.setAttribute("blueprintId", blueprintId); + if (choiceUrl != null) + availablePick.setAttribute("url", choiceUrl); + availablePicksElem.appendChild(availablePick); + } + + responseWriter.writeXmlResponse(doc); + } + + private League findLeagueByType(String leagueType) { + for (League activeLeague : _leagueService.getActiveLeagues()) { + if (activeLeague.getType().equals(leagueType)) + return activeLeague; + } + return null; + } + + private void makePick(HttpRequest request, String leagueType, ResponseWriter responseWriter) throws Exception { + HttpPostRequestDecoder postDecoder = new HttpPostRequestDecoder(request); + String participantId = getFormParameterSafely(postDecoder, "participantId"); + String selectedChoiceId = getFormParameterSafely(postDecoder, "choiceId"); + + League league = findLeagueByType(leagueType); + + if (league == null) + responseWriter.writeError(404); + + LeagueData leagueData = league.getLeagueData(_cardSets, _soloDraftDefinitions); + if (!leagueData.isSoloDraftLeague()) + responseWriter.writeError(404); + + SoloDraftLeagueData soloDraftLeagueData = (SoloDraftLeagueData) leagueData; + CollectionType collectionType = soloDraftLeagueData.getCollectionType(); + + Player resourceOwner = getResourceOwnerSafely(request, participantId); + + CardCollection collection = _collectionsManager.getPlayerCollection(resourceOwner, collectionType.getCode()); + boolean finished = (Boolean) collection.getExtraInformation().get("finished"); + if (finished) + responseWriter.writeError(404); + + int stage = ((Number) collection.getExtraInformation().get("stage")).intValue(); + long playerSeed = ((Number) collection.getExtraInformation().get("seed")).longValue(); + + SoloDraft soloDraft = soloDraftLeagueData.getSoloDraft(); + Iterable possibleChoices = soloDraft.getAvailableChoices(playerSeed, stage); + + SoloDraft.DraftChoice draftChoice = getSelectedDraftChoice(selectedChoiceId, possibleChoices); + if (draftChoice == null) + responseWriter.writeError(400); + + CardCollection selectedCards = soloDraft.getCardsForChoiceId(selectedChoiceId, playerSeed, stage); + Map extraInformationChanges = new HashMap(); + boolean hasNextStage = soloDraft.hasNextStage(playerSeed, stage); + extraInformationChanges.put("stage", stage+1); + if (!hasNextStage) + extraInformationChanges.put("finished", true); + + _collectionsManager.addItemsToPlayerCollection(false, "Draft pick", resourceOwner, collectionType, selectedCards.getAll().values(), extraInformationChanges); + + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + + Document doc = documentBuilder.newDocument(); + + Element pickResultElem = doc.createElement("pickResult"); + doc.appendChild(pickResultElem); + + for (CardCollection.Item item : selectedCards.getAll().values()) { + Element pickedCard = doc.createElement("pickedCard"); + pickedCard.setAttribute("blueprintId", item.getBlueprintId()); + pickedCard.setAttribute("count", String.valueOf(item.getCount())); + pickResultElem.appendChild(pickedCard); + } + + if (hasNextStage) { + Iterable availableChoices = soloDraft.getAvailableChoices(playerSeed, stage+1); + for (SoloDraft.DraftChoice availableChoice : availableChoices) { + String choiceId = availableChoice.getChoiceId(); + String blueprintId = availableChoice.getBlueprintId(); + String choiceUrl = availableChoice.getChoiceUrl(); + Element availablePick = doc.createElement("availablePick"); + availablePick.setAttribute("id", choiceId); + if (blueprintId != null) + availablePick.setAttribute("blueprintId", blueprintId); + if (choiceUrl != null) + availablePick.setAttribute("url", choiceUrl); + pickResultElem.appendChild(availablePick); + } + } + + responseWriter.writeXmlResponse(doc); + } + + private SoloDraft.DraftChoice getSelectedDraftChoice(String choiceId, Iterable availableChoices) { + for (SoloDraft.DraftChoice availableChoice : availableChoices) { + if (availableChoice.getChoiceId().equals(choiceId)) + return availableChoice; + } + return null; + } +} diff --git a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/LeagueRequestHandler.java b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/LeagueRequestHandler.java index f63b26e28..d4105f335 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/LeagueRequestHandler.java +++ b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/LeagueRequestHandler.java @@ -100,7 +100,7 @@ public class LeagueRequestHandler extends LotroServerRequestHandler implements U leagueElem.setAttribute("member", String.valueOf(inLeague)); leagueElem.setAttribute("joinable", String.valueOf(!inLeague && end >= DateUtils.getCurrentDate())); - leagueElem.setAttribute("draftable", String.valueOf(inLeague && leagueData.isDraftLeague())); + leagueElem.setAttribute("draftable", String.valueOf(inLeague && leagueData.isSoloDraftLeague())); leagueElem.setAttribute("type", league.getType()); leagueElem.setAttribute("name", league.getName()); leagueElem.setAttribute("cost", String.valueOf(league.getCost())); diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/collection/CollectionsManager.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/collection/CollectionsManager.java index 94ab61ff6..1c7ba5949 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/collection/CollectionsManager.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/collection/CollectionsManager.java @@ -186,7 +186,7 @@ public class CollectionsManager { return result; } - public void addItemsToPlayerCollection(boolean notifyPlayer, String reason, Player player, CollectionType collectionType, Collection items) { + public void addItemsToPlayerCollection(boolean notifyPlayer, String reason, Player player, CollectionType collectionType, Collection items, Map extraInformation) { _readWriteLock.writeLock().lock(); try { final CardCollection playerCollection = getPlayerCollection(player, collectionType.getCode()); @@ -198,6 +198,12 @@ public class CollectionsManager { addedCards.addItem(item.getBlueprintId(), item.getCount()); } + if (extraInformation != null) { + Map resultExtraInformation = new HashMap(playerCollection.getExtraInformation()); + resultExtraInformation.putAll(extraInformation); + mutableCardCollection.setExtraInformation(resultExtraInformation); + } + setPlayerCollection(player, collectionType.getCode(), mutableCardCollection); _transferDAO.addTransferTo(notifyPlayer, player.getName(), reason, collectionType.getFullName(), 0, addedCards); } @@ -206,6 +212,10 @@ public class CollectionsManager { } } + public void addItemsToPlayerCollection(boolean notifyPlayer, String reason, Player player, CollectionType collectionType, Collection items) { + addItemsToPlayerCollection(notifyPlayer, reason, player, collectionType, items, null); + } + public void addItemsToPlayerCollection(boolean notifyPlayer, String reason, String player, CollectionType collectionType, Collection items) { addItemsToPlayerCollection(notifyPlayer, reason, _playerDAO.getPlayer(player), collectionType, items); } diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/ConstructedLeagueData.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/ConstructedLeagueData.java index 7de24c08c..861833e89 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/ConstructedLeagueData.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/ConstructedLeagueData.java @@ -43,7 +43,7 @@ public class ConstructedLeagueData implements LeagueData { } @Override - public boolean isDraftLeague() { + public boolean isSoloDraftLeague() { return false; } diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueData.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueData.java index 4e0104937..c7ab7f91c 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueData.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/LeagueData.java @@ -8,7 +8,7 @@ import com.gempukku.lotro.game.Player; import java.util.List; public interface LeagueData { - public boolean isDraftLeague(); + public boolean isSoloDraftLeague(); public List getSeries(); diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/NewConstructedLeagueData.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/NewConstructedLeagueData.java index 7655c8cc5..1da001142 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/NewConstructedLeagueData.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/NewConstructedLeagueData.java @@ -46,7 +46,7 @@ public class NewConstructedLeagueData implements LeagueData { } @Override - public boolean isDraftLeague() { + public boolean isSoloDraftLeague() { return false; } diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/NewSealedLeagueData.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/NewSealedLeagueData.java index 57e66c4bc..534df97f1 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/NewSealedLeagueData.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/NewSealedLeagueData.java @@ -47,7 +47,7 @@ public class NewSealedLeagueData implements LeagueData { } @Override - public boolean isDraftLeague() { + public boolean isSoloDraftLeague() { return false; } diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/SealedLeagueData.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/SealedLeagueData.java index c72434abf..968a6798b 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/SealedLeagueData.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/SealedLeagueData.java @@ -47,7 +47,7 @@ public class SealedLeagueData implements LeagueData { } @Override - public boolean isDraftLeague() { + public boolean isSoloDraftLeague() { return false; } diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/DraftLeagueData.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/SoloDraftLeagueData.java similarity index 89% rename from gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/DraftLeagueData.java rename to gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/SoloDraftLeagueData.java index 753f33531..0d1b3d66d 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/DraftLeagueData.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/league/SoloDraftLeagueData.java @@ -14,14 +14,14 @@ import com.gempukku.lotro.game.Player; import java.util.*; -public class DraftLeagueData implements LeagueData { +public class SoloDraftLeagueData implements LeagueData { private SoloDraft _draft; private CollectionType _collectionType; private CollectionType _prizeCollectionType = CollectionType.MY_CARDS; private LeaguePrizes _leaguePrizes; private LeagueSerieData _serie; - public DraftLeagueData(CardSets cardSets, SoloDraftDefinitions soloDraftDefinitions, String parameters) { + public SoloDraftLeagueData(CardSets cardSets, SoloDraftDefinitions soloDraftDefinitions, String parameters) { _leaguePrizes = new FixedLeaguePrizes(cardSets); String[] params = parameters.split(","); @@ -37,8 +37,16 @@ public class DraftLeagueData implements LeagueData { _draft.getFormat(), _collectionType); } + public CollectionType getCollectionType() { + return _collectionType; + } + + public SoloDraft getSoloDraft() { + return _draft; + } + @Override - public boolean isDraftLeague() { + public boolean isSoloDraftLeague() { return true; } @@ -54,22 +62,24 @@ public class DraftLeagueData implements LeagueData { @Override public CardCollection joinLeague(CollectionsManager collectionsManager, Player player, int currentTime) { MutableCardCollection startingCollection = new DefaultCardCollection(); + long seed = getSeed(player); if (currentTime >= _serie.getStart()) { - CardCollection leagueProduct = _draft.initializeNewCollection(getSeed(player)); + CardCollection leagueProduct = _draft.initializeNewCollection(seed); for (Map.Entry serieCollectionItem : leagueProduct.getAll().entrySet()) startingCollection.addItem(serieCollectionItem.getKey(), serieCollectionItem.getValue().getCount()); } - startingCollection.setExtraInformation(createExtraInformation()); + startingCollection.setExtraInformation(createExtraInformation(seed)); collectionsManager.addPlayerCollection(false, "Sealed league product", player, _collectionType, startingCollection); return startingCollection; } - private Map createExtraInformation() { + private Map createExtraInformation(long seed) { Map extraInformation = new HashMap(); extraInformation.put("finished", false); extraInformation.put("stage", 0); + extraInformation.put("seed", seed); return extraInformation; }