From 03751d6b9d6df8313fd44f240da4b0cad8472ab1 Mon Sep 17 00:00:00 2001 From: Christian 'ketura' McCarty Date: Tue, 25 Oct 2022 02:14:18 -0500 Subject: [PATCH] Various changes relating to the collection rework; not yet done or working --- gemp-lotr/db/create-collection_entries.sql | 18 +++ .../handler/GameHistoryRequestHandler.java | 74 ++++++------ .../async/handler/PlaytestRequestHandler.java | 12 +- .../resources/sealed/sealed_formats.hjson | 4 +- .../com/gempukku/lotro/common/DBDefs.java | 56 +++++++++ .../lotro/collection/CachedCollectionDAO.java | 23 ++++ .../lotro/collection/CollectionsManager.java | 60 +++------- .../com/gempukku/lotro/db/CollectionDAO.java | 6 + .../java/com/gempukku/lotro/db/DbAccess.java | 18 ++- .../gempukku/lotro/db/DbCollectionDAO.java | 107 ++++++++++++++++++ .../gempukku/lotro/db/DbGameHistoryDAO.java | 35 +++--- .../com/gempukku/lotro/db/GameHistoryDAO.java | 8 +- .../lotro/db/vo/GameHistoryEntry.java | 35 ------ .../lotro/game/CompleteCardCollection.java | 54 +++++++++ .../lotro/game/DefaultCardCollection.java | 18 +-- .../lotro/game/GameHistoryService.java | 8 +- .../lotro/cards/GenericCardTestHelper.java | 19 +++- 17 files changed, 393 insertions(+), 162 deletions(-) create mode 100644 gemp-lotr/db/create-collection_entries.sql create mode 100644 gemp-lotr/gemp-lotr-common/src/main/java/com/gempukku/lotro/common/DBDefs.java create mode 100644 gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/CompleteCardCollection.java diff --git a/gemp-lotr/db/create-collection_entries.sql b/gemp-lotr/db/create-collection_entries.sql new file mode 100644 index 000000000..cd4458df7 --- /dev/null +++ b/gemp-lotr/db/create-collection_entries.sql @@ -0,0 +1,18 @@ + + +ALTER TABLE collection ADD CONSTRAINT fk_collection_player_id FOREIGN KEY (player_id) REFERENCES player(id); + + +CREATE TABLE `collection_entries` ( + `collection_id` int(11) NOT NULL, + `quantity` int(2) DEFAULT 0, + `product_type` varchar(50) NOT NULL, + `product_variant` varchar(50) DEFAULT NULL, + `product` varchar(50) NOT NULL, + `source` varchar(50) NOT NULL, + `created_date` datetime DEFAULT current_timestamp(), + `modified_date` datetime DEFAULT NULL ON UPDATE current_timestamp(), + `notes` varchar(100) DEFAULT NULL, + PRIMARY KEY (`collection_id`, `product`), + CONSTRAINT `collection_entries_ibfk_1` FOREIGN KEY (`collection_id`) REFERENCES `collection` (`id`) +) ; \ No newline at end of file diff --git a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/GameHistoryRequestHandler.java b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/GameHistoryRequestHandler.java index b73241488..97453252c 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/GameHistoryRequestHandler.java +++ b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/GameHistoryRequestHandler.java @@ -2,7 +2,7 @@ package com.gempukku.lotro.async.handler; import com.gempukku.lotro.async.HttpProcessingException; import com.gempukku.lotro.async.ResponseWriter; -import com.gempukku.lotro.db.vo.GameHistoryEntry; +import com.gempukku.lotro.common.DBDefs; import com.gempukku.lotro.game.GameHistoryService; import com.gempukku.lotro.game.Player; import io.netty.handler.codec.http.HttpMethod; @@ -42,7 +42,7 @@ public class GameHistoryRequestHandler extends LotroServerRequestHandler impleme Player resourceOwner = getResourceOwnerSafely(request, participantId); - final List playerGameHistory = _gameHistoryService.getGameHistoryForPlayer(resourceOwner, start, count); + final List playerGameHistory = _gameHistoryService.getGameHistoryForPlayer(resourceOwner, start, count); int recordCount = _gameHistoryService.getGameHistoryForPlayerCount(resourceOwner); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); @@ -52,29 +52,29 @@ public class GameHistoryRequestHandler extends LotroServerRequestHandler impleme gameHistory.setAttribute("count", String.valueOf(recordCount)); gameHistory.setAttribute("playerId", resourceOwner.getName()); - for (GameHistoryEntry gameHistoryEntry : playerGameHistory) { + for (DBDefs.GameHistory game : playerGameHistory) { Element historyEntry = doc.createElement("historyEntry"); - historyEntry.setAttribute("winner", gameHistoryEntry.winner); - historyEntry.setAttribute("loser", gameHistoryEntry.loser); + historyEntry.setAttribute("winner", game.winner); + historyEntry.setAttribute("loser", game.loser); - historyEntry.setAttribute("winReason", gameHistoryEntry.win_reason); - historyEntry.setAttribute("loseReason", gameHistoryEntry.lose_reason); + historyEntry.setAttribute("winReason", game.win_reason); + historyEntry.setAttribute("loseReason", game.lose_reason); - historyEntry.setAttribute("formatName", gameHistoryEntry.format_name); - String tournament = gameHistoryEntry.tournament; + historyEntry.setAttribute("formatName", game.format_name); + String tournament = game.tournament; if (tournament != null) historyEntry.setAttribute("tournament", tournament); - if (gameHistoryEntry.winner.equals(resourceOwner.getName()) && gameHistoryEntry.win_recording_id != null) { - historyEntry.setAttribute("gameRecordingId", gameHistoryEntry.win_recording_id); - historyEntry.setAttribute("deckName", gameHistoryEntry.winner_deck_name); - } else if (gameHistoryEntry.loser.equals(resourceOwner.getName()) && gameHistoryEntry.lose_recording_id != null) { - historyEntry.setAttribute("gameRecordingId", gameHistoryEntry.lose_recording_id); - historyEntry.setAttribute("deckName", gameHistoryEntry.loser_deck_name); + if (game.winner.equals(resourceOwner.getName()) && game.win_recording_id != null) { + historyEntry.setAttribute("gameRecordingId", game.win_recording_id); + historyEntry.setAttribute("deckName", game.winner_deck_name); + } else if (game.loser.equals(resourceOwner.getName()) && game.lose_recording_id != null) { + historyEntry.setAttribute("gameRecordingId", game.lose_recording_id); + historyEntry.setAttribute("deckName", game.loser_deck_name); } - historyEntry.setAttribute("startTime", String.valueOf(gameHistoryEntry.GetStartDate().getTime())); - historyEntry.setAttribute("endTime", String.valueOf(gameHistoryEntry.GetEndDate().getTime())); + historyEntry.setAttribute("startTime", String.valueOf(game.GetStartDate().getTime())); + historyEntry.setAttribute("endTime", String.valueOf(game.GetEndDate().getTime())); gameHistory.appendChild(historyEntry); } @@ -83,7 +83,7 @@ public class GameHistoryRequestHandler extends LotroServerRequestHandler impleme responseWriter.writeXmlResponse(doc); } else if (uri.equals("/list") && request.method() == HttpMethod.GET) { - final List playerGameHistory = _gameHistoryService.getTrackableGames(100); + final List playerGameHistory = _gameHistoryService.getTrackableGames(100); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); @@ -92,24 +92,24 @@ public class GameHistoryRequestHandler extends LotroServerRequestHandler impleme DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - for (GameHistoryEntry gameHistoryEntry : playerGameHistory) { + for (DBDefs.GameHistory game : playerGameHistory) { Element historyEntry = doc.createElement("historyEntry"); - historyEntry.setAttribute("winner", gameHistoryEntry.winner); - historyEntry.setAttribute("loser", gameHistoryEntry.loser); + historyEntry.setAttribute("winner", game.winner); + historyEntry.setAttribute("loser", game.loser); - historyEntry.setAttribute("winReason", gameHistoryEntry.win_reason); - historyEntry.setAttribute("loseReason", gameHistoryEntry.lose_reason); + historyEntry.setAttribute("winReason", game.win_reason); + historyEntry.setAttribute("loseReason", game.lose_reason); - historyEntry.setAttribute("formatName", gameHistoryEntry.format_name); + historyEntry.setAttribute("formatName", game.format_name); - historyEntry.setAttribute("winnerRecordingLink", "http://www.gempukku.com/gemp-lotr/game.html?replayId="+gameHistoryEntry.winner+"$"+gameHistoryEntry.win_recording_id); - historyEntry.setAttribute("winnerDeckName", gameHistoryEntry.winner_deck_name); + historyEntry.setAttribute("winnerRecordingLink", "http://www.gempukku.com/gemp-lotr/game.html?replayId="+game.winner+"$"+game.win_recording_id); + historyEntry.setAttribute("winnerDeckName", game.winner_deck_name); - historyEntry.setAttribute("loserRecordingLink", "http://www.gempukku.com/gemp-lotr/game.html?replayId="+gameHistoryEntry.loser+"$"+gameHistoryEntry.lose_recording_id); - historyEntry.setAttribute("loserDeckName", gameHistoryEntry.loser_deck_name); + historyEntry.setAttribute("loserRecordingLink", "http://www.gempukku.com/gemp-lotr/game.html?replayId="+game.loser+"$"+game.lose_recording_id); + historyEntry.setAttribute("loserDeckName", game.loser_deck_name); - historyEntry.setAttribute("startTime", dateFormat.format(new Date(gameHistoryEntry.GetStartDate().getTime()))); - historyEntry.setAttribute("endTime", dateFormat.format(new Date(gameHistoryEntry.GetEndDate().getTime()))); + historyEntry.setAttribute("startTime", dateFormat.format(new Date(game.GetStartDate().getTime()))); + historyEntry.setAttribute("endTime", dateFormat.format(new Date(game.GetEndDate().getTime()))); gameHistory.appendChild(historyEntry); } @@ -118,7 +118,7 @@ public class GameHistoryRequestHandler extends LotroServerRequestHandler impleme responseWriter.writeXmlResponse(doc); } else if (uri.equals("/list/html") && request.method() == HttpMethod.GET) { - final List playerGameHistory = _gameHistoryService.getTrackableGames(100); + final List playerGameHistory = _gameHistoryService.getTrackableGames(100); StringBuilder sb = new StringBuilder(); sb.append(""); @@ -133,16 +133,16 @@ public class GameHistoryRequestHandler extends LotroServerRequestHandler impleme DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - for (GameHistoryEntry gameHistoryEntry : playerGameHistory) { - String winnerLink = "http://www.gempukku.com/gemp-lotr/game.html?replayId=" + gameHistoryEntry.winner + "$" + gameHistoryEntry.win_recording_id; - String loserLink = "http://www.gempukku.com/gemp-lotr/game.html?replayId=" + gameHistoryEntry.loser + "$" + gameHistoryEntry.lose_recording_id; + for (DBDefs.GameHistory game : playerGameHistory) { + String winnerLink = "http://www.gempukku.com/gemp-lotr/game.html?replayId=" + game.winner + "$" + game.win_recording_id; + String loserLink = "http://www.gempukku.com/gemp-lotr/game.html?replayId=" + game.loser + "$" + game.lose_recording_id; sb.append(""); - sb.append(""); - sb.append(""); + sb.append(""); + sb.append(""); sb.append(""); sb.append(""); - sb.append(""); + sb.append(""); sb.append(""); } diff --git a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/PlaytestRequestHandler.java b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/PlaytestRequestHandler.java index f0227c708..e4c583bae 100644 --- a/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/PlaytestRequestHandler.java +++ b/gemp-lotr/gemp-lotr-async/src/main/java/com/gempukku/lotro/async/handler/PlaytestRequestHandler.java @@ -2,20 +2,22 @@ package com.gempukku.lotro.async.handler; import com.gempukku.lotro.async.HttpProcessingException; import com.gempukku.lotro.async.ResponseWriter; +import com.gempukku.lotro.common.DBDefs; import com.gempukku.lotro.db.PlayerDAO; -import com.gempukku.lotro.db.vo.GameHistoryEntry; -import com.gempukku.lotro.game.*; +import com.gempukku.lotro.game.GameHistoryService; +import com.gempukku.lotro.game.Player; +import com.google.gson.Gson; import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.gson.Gson; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.lang.reflect.Type; -import java.util.*; +import java.util.List; +import java.util.Map; public class PlaytestRequestHandler extends LotroServerRequestHandler implements UriRequestHandler { @@ -98,7 +100,7 @@ public class PlaytestRequestHandler extends LotroServerRequestHandler implements String format = getFormParameterSafely(postDecoder, "format"); int count = Integer.parseInt(getFormParameterSafely(postDecoder, "count")); - final List gameHistory = _gameHistoryService.getGameHistoryForFormat(format, count); + final List gameHistory = _gameHistoryService.getGameHistoryForFormat(format, count); responseWriter.writeJsonResponse(JsonConvert.toJson(gameHistory)); diff --git a/gemp-lotr/gemp-lotr-cards/src/main/resources/sealed/sealed_formats.hjson b/gemp-lotr/gemp-lotr-cards/src/main/resources/sealed/sealed_formats.hjson index c457d376a..dfbead09e 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/resources/sealed/sealed_formats.hjson +++ b/gemp-lotr/gemp-lotr-cards/src/main/resources/sealed/sealed_formats.hjson @@ -1512,7 +1512,7 @@ 12xRoS - Booster 12xTaD - Booster #Frodo, Weary From the Journey - 1x11_144 + 1x15_144 #The One Ring, The Ruling Ring 1x15_2 #Anduin River @@ -1563,7 +1563,7 @@ format: limited_multipath seriesProduct: [ [ - 1x(S)Movie Special Choice - Starter + 1x(S)Movie Choice - Starter 1xFotR - Booster 1xMoM - Booster 1xRotEL - Booster diff --git a/gemp-lotr/gemp-lotr-common/src/main/java/com/gempukku/lotro/common/DBDefs.java b/gemp-lotr/gemp-lotr-common/src/main/java/com/gempukku/lotro/common/DBDefs.java new file mode 100644 index 000000000..212d48c0e --- /dev/null +++ b/gemp-lotr/gemp-lotr-common/src/main/java/com/gempukku/lotro/common/DBDefs.java @@ -0,0 +1,56 @@ +package com.gempukku.lotro.common; + +import java.time.LocalDateTime; +import java.util.Date; + +public class DBDefs { + + public static class GameHistory { + + public int id; + + public String winner; + public String loser; + + public String win_reason; + public String lose_reason; + + public String win_recording_id; + public String lose_recording_id; + + public long start_date; + public long end_date; + + public String format_name; + + public String winner_deck_name; + public String loser_deck_name; + + public String tournament; + + + public Date GetStartDate() + { + return new Date(start_date); + } + + public Date GetEndDate() + { + return new Date(end_date); + } + + + } + + public static class CollectionEntry { + public int collection_id; + public int quantity; + public String product_type; + public String product_variant; + public String product; + public String source; + public LocalDateTime created_date; + public LocalDateTime modified_date; + public String notes; + } +} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/collection/CachedCollectionDAO.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/collection/CachedCollectionDAO.java index 3fda1c5bf..357d6905e 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/collection/CachedCollectionDAO.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/collection/CachedCollectionDAO.java @@ -53,4 +53,27 @@ public class CachedCollectionDAO implements CollectionDAO, Cached { _delegate.setPlayerCollection(playerId, type, collection); _playerCollections.put(constructCacheKey(playerId, type), collection); } + + @Override + public void convertCollection(int playerId, String type) throws SQLException, IOException { + _delegate.convertCollection(playerId, type); + } + + @Override + public void addToCollection(int playerId, String type, CardCollection collection, String source) { + _delegate.addToCollection(playerId, type, collection, source); + String id = constructCacheKey(playerId, type); + if(!_playerCollections.containsKey(id)) { + _playerCollections.put(id, collection); + } + else { + var oldCollection = _playerCollections.get(id); + //oldCollection. + } + } + + @Override + public void removeFromCollection(int playerId, String type, CardCollection collection, String source) { + _delegate.removeFromCollection(playerId, type, collection, source); + } } 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 f10d00599..6905845a2 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 @@ -1,19 +1,18 @@ package com.gempukku.lotro.collection; -import com.gempukku.lotro.common.CardType; import com.gempukku.lotro.db.CollectionDAO; import com.gempukku.lotro.db.PlayerDAO; import com.gempukku.lotro.db.vo.CollectionType; import com.gempukku.lotro.game.*; -import com.gempukku.lotro.packs.PacksStorage; import com.gempukku.lotro.packs.ProductLibrary; -import com.google.common.collect.Iterables; import java.io.IOException; import java.sql.SQLException; -import java.util.*; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.stream.Collectors; public class CollectionsManager { private final ReentrantReadWriteLock _readWriteLock = new ReentrantReadWriteLock(); @@ -31,46 +30,7 @@ public class CollectionsManager { } public CardCollection getDefaultCollection() { - return new CardCollection() { - @Override - public int getCurrency() { - return 0; - } - - @Override - public Iterable getAll() { - return lotroCardBlueprintLibrary.getBaseCards().entrySet().stream().map(cardBlueprintEntry -> { - String blueprintId = cardBlueprintEntry.getKey(); - int count = getCount(cardBlueprintEntry.getValue()); - return Item.createItem(blueprintId, count); - }).collect(Collectors.toList()); - } - - @Override - public int getItemCount(String blueprintId) { - final String baseBlueprintId = lotroCardBlueprintLibrary.getBaseBlueprintId(blueprintId); - if (baseBlueprintId.equals(blueprintId)) { - try { - return getCount(lotroCardBlueprintLibrary.getLotroCardBlueprint(blueprintId)); - } catch (CardNotFoundException exp) { - return 0; - } - } - return 0; - } - - private int getCount(LotroCardBlueprint blueprint) { - final CardType cardType = blueprint.getCardType(); - if (cardType == CardType.SITE || cardType == CardType.THE_ONE_RING) - return 1; - return 4; - } - - @Override - public Map getExtraInformation() { - return Collections.emptyMap(); - } - }; + return new CompleteCardCollection(lotroCardBlueprintLibrary); } public CardCollection getPlayerCollection(String playerName, String collectionType) { @@ -134,6 +94,16 @@ public class CollectionsManager { } } + public void upgradePlayerCollection(Player player, CollectionType colltype) throws SQLException, IOException { + _readWriteLock.writeLock().lock(); + try { + //var collection = _collectionDAO.getPlayerCollection(player.getId(), colltype.getCode()); + _collectionDAO.convertCollection(player.getId(), colltype.getCode()); + } finally { + _readWriteLock.writeLock().unlock(); + } + } + public Map getPlayersCollection(String collectionType) { if (collectionType.contains("+")) throw new IllegalArgumentException("Invalid collection type: " + collectionType); diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/CollectionDAO.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/CollectionDAO.java index 29c2784e5..518377edf 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/CollectionDAO.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/CollectionDAO.java @@ -12,4 +12,10 @@ public interface CollectionDAO { public CardCollection getPlayerCollection(int playerId, String type) throws SQLException, IOException; public void setPlayerCollection(int playerId, String type, CardCollection collection) throws SQLException, IOException; + + void convertCollection(int playerId, String type) throws SQLException, IOException; + + void addToCollection(int playerId, String type, CardCollection collection, String source); + + void removeFromCollection(int playerId, String type, CardCollection collection, String source); } diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbAccess.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbAccess.java index d274e97b7..1be67fbef 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbAccess.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbAccess.java @@ -8,25 +8,30 @@ import org.apache.commons.dbcp.PoolingDataSource; import org.apache.commons.pool.impl.GenericObjectPool; import javax.sql.DataSource; +import java.util.Properties; public class DbAccess { private final DataSource _dataSource; public DbAccess() { + this(AppConfig.getProperty("db.connection.url"), AppConfig.getProperty("db.connection.username"), AppConfig.getProperty("db.connection.password"), false); + } + + public DbAccess(String url, String user, String pass, boolean batch) { try { Class.forName(AppConfig.getProperty("db.connection.class")); } catch (ClassNotFoundException e) { throw new RuntimeException("Couldn't find the DB driver", e); } - _dataSource = setupDataSource(AppConfig.getProperty("db.connection.url")); + _dataSource = setupDataSource(url, user, pass, batch); } public DataSource getDataSource() { return _dataSource; } - private DataSource setupDataSource(String connectURI) { + private DataSource setupDataSource(String connectURI, String user, String pass, Boolean batch) { // // First, we'll create a ConnectionFactory that the // pool will use to create Connections. @@ -34,9 +39,14 @@ public class DbAccess { // using the connect string passed in the command line // arguments. // + Properties props = new Properties() {{ + setProperty("user", user); + setProperty("password", pass); + setProperty("rewriteBatchedStatements", batch.toString().toLowerCase()); + setProperty("innodb_autoinc_lock_mode", "2"); + }}; ConnectionFactory connectionFactory = - new DriverManagerConnectionFactory(connectURI, AppConfig.getProperty("db.connection.username"), - AppConfig.getProperty("db.connection.password")); + new DriverManagerConnectionFactory(connectURI, props); // // Now we'll need a ObjectPool that serves as the diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbCollectionDAO.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbCollectionDAO.java index 4e06506c8..6df5fd549 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbCollectionDAO.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbCollectionDAO.java @@ -2,6 +2,8 @@ package com.gempukku.lotro.db; import com.gempukku.lotro.collection.CollectionSerializer; import com.gempukku.lotro.game.CardCollection; +import org.sql2o.Query; +import org.sql2o.Sql2o; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -85,4 +87,109 @@ public class DbCollectionDAO implements CollectionDAO { } } } + + private class intContainer { + public int ID; + } + + public int getCollectionID(int playerId, String type) { + try { + + Sql2o db = new Sql2o(_dbAccess.getDataSource()); + + try (org.sql2o.Connection conn = db.open()) { + String sql = """ + SELECT + ID + FROM collection + WHERE type = :type + AND player_id = :playerID + LIMIT 1 + """; + intContainer result = conn.createQuery(sql) + .addParameter("type", type) + .addParameter("playerID", playerId) + .executeAndFetch(intContainer.class) + .stream().findFirst().orElse(null); + + return result.ID; + } + } catch (Exception ex) { + throw new RuntimeException("Unable to retrieve collection ID", ex); + } + } + + public void updateCollection(int playerId, String type, CardCollection collection, String source) { + String sql = """ + INSERT INTO collection_entries(collection_id, quantity, product_type, product, source) + VALUES (:collid, :quantity, :type, :product, :source) + ON DUPLICATE KEY UPDATE quantity = :quantity, source = :source; + """; + String error = "Unable to update product via upsert into collection_entries."; + updateCollection(playerId, type, collection, source, sql, error); + } + + public void addToCollection(int playerId, String type, CardCollection collection, String source) { + String sql = """ + INSERT INTO collection_entries(collection_id, quantity, product_type, product, source) + VALUES (:collid, :quantity, :type, :product, :source) + ON DUPLICATE KEY UPDATE quantity = quantity + :quantity, source = :source; + """; + String error = "Unable to add product via upsert into collection_entries."; + updateCollection(playerId, type, collection, source, sql, error); + } + + public void removeFromCollection(int playerId, String type, CardCollection collection, String source) { + String sql = """ + INSERT INTO collection_entries(collection_id, quantity, product_type, product, source) + VALUES (:collid, :quantity, :type, :product, :source) + ON DUPLICATE KEY UPDATE quantity = GREATEST(quantity - :quantity, 0), source = :source; + """; + String error = "Unable to remove product via upsert into collection_entries."; + updateCollection(playerId, type, collection, source, sql, error); + } + + public void convertCollection(int playerId, String type) throws SQLException, IOException { + CardCollection oldCollection = getPlayerCollection(playerId, type); + updateCollection(playerId, type, oldCollection, "Initial Convert"); + } + + + //TODO: + // - Convert currency to an extra info entry + // - add data field to the original collection table to hold the extra info as json + // - create player-looping function to convert all collections and see if it blows up via test + // - add CollectionsManager mirror functions to read/writing into the new table + // - write unit tests to convert and compare a bajillion collections + // - sunset the old collection handling functions + // - test a: draft, new art card reward, my cards reward, pack openings + // - write script to back up db and delete the old binary blob column + // - write script to convert all leagues to use IDs instead of names + private void updateCollection(int playerId, String type, CardCollection collection, String source, String sql, String error) { + int collID = getCollectionID(playerId, type); + + try { + Sql2o db = new Sql2o(_dbAccess.getDataSource()); + + try (org.sql2o.Connection conn = db.beginTransaction()) { + Query query = conn.createQuery(sql, true); + int i = 0; + //TODO: maybe detect when the batch is 1000 entries long and execute then to prevent errors + for(var card : collection.getAll()) { + query.addParameter("collid", collID) + .addParameter("quantity", card.getCount()) + .addParameter("type", card.getType()) + .addParameter("product", card.getBlueprintId()) + .addParameter("source", source) + .addToBatch(); + } + query.executeBatch(); + conn.commit(); + } + } catch (Exception ex) { + throw new RuntimeException(error, ex); + } + } + + } diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbGameHistoryDAO.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbGameHistoryDAO.java index 31d9a5cf1..5bda87e5d 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbGameHistoryDAO.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/DbGameHistoryDAO.java @@ -1,6 +1,6 @@ package com.gempukku.lotro.db; -import com.gempukku.lotro.db.vo.GameHistoryEntry; +import com.gempukku.lotro.common.DBDefs; import com.gempukku.lotro.game.Player; import org.sql2o.Sql2o; @@ -42,7 +42,7 @@ public class DbGameHistoryDAO implements GameHistoryDAO { } } - public List getGameHistoryForPlayer(Player player, int start, int count) { + public List getGameHistoryForPlayer(Player player, int start, int count) { try { @@ -50,11 +50,11 @@ public class DbGameHistoryDAO implements GameHistoryDAO { try (org.sql2o.Connection conn = db.open()) { String sql = "select winner, loser, win_reason, lose_reason, win_recording_id, lose_recording_id, format_name, tournament, winner_deck_name, loser_deck_name, start_date, end_date from game_history where winner=:playerName or loser=:playerName order by end_date desc limit :start, :count"; - List result = conn.createQuery(sql) + List result = conn.createQuery(sql) .addParameter("playerName", player.getName()) .addParameter("start", start) .addParameter("count", count) - .executeAndFetch(GameHistoryEntry.class); + .executeAndFetch(DBDefs.GameHistory.class); return result; } @@ -65,20 +65,27 @@ public class DbGameHistoryDAO implements GameHistoryDAO { } @Override - public List getGameHistoryForFormat(String format, int count) { + public List getGameHistoryForFormat(String format, int count) { try { Sql2o db = new Sql2o(_dbAccess.getDataSource()); try (org.sql2o.Connection conn = db.open()) { - String sql = "SELECT winner, loser, win_reason, lose_reason, win_recording_id, lose_recording_id, format_name, tournament, winner_deck_name, loser_deck_name, start_date, end_date " + - " FROM game_history " + - " WHERE format_name LIKE :format" + - " ORDER BY end_date DESC LIMIT :count"; - List result = conn.createQuery(sql) + String sql = """ + SELECT + winner, loser, win_reason, lose_reason, + win_recording_id, lose_recording_id, format_name, + tournament, winner_deck_name, loser_deck_name, + start_date, end_date + FROM game_history + WHERE format_name LIKE :format + ORDER BY end_date DESC + LIMIT :count + """; + List result = conn.createQuery(sql) .addParameter("format", "%" + format + "%") .addParameter("count", count) - .executeAndFetch(GameHistoryEntry.class); + .executeAndFetch(DBDefs.GameHistory.class); return result; } @@ -191,7 +198,7 @@ public class DbGameHistoryDAO implements GameHistoryDAO { } @Override - public List getLastGames(String requestedFormatName, int count) { + public List getLastGames(String requestedFormatName, int count) { try { @@ -201,10 +208,10 @@ public class DbGameHistoryDAO implements GameHistoryDAO { String sql = "select winner, loser, win_reason, lose_reason, win_recording_id, lose_recording_id, format_name, " + "tournament, winner_deck_name, loser_deck_name, start_date, end_date from game_history " + "where format_name=:formatName order by end_date desc limit :count"; - List result = conn.createQuery(sql) + List result = conn.createQuery(sql) .addParameter("formatName", requestedFormatName) .addParameter("count", count) - .executeAndFetch(GameHistoryEntry.class); + .executeAndFetch(DBDefs.GameHistory.class); return result; } diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/GameHistoryDAO.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/GameHistoryDAO.java index 94e85d354..236cced60 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/GameHistoryDAO.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/GameHistoryDAO.java @@ -1,6 +1,6 @@ package com.gempukku.lotro.db; -import com.gempukku.lotro.db.vo.GameHistoryEntry; +import com.gempukku.lotro.common.DBDefs; import com.gempukku.lotro.game.Player; import java.util.Date; @@ -10,11 +10,11 @@ import java.util.Map; public interface GameHistoryDAO { public void addGameHistory(String winner, String loser, String winReason, String loseReason, String winRecordingId, String loseRecordingId, String formatName, String tournament, String winnerDeckName, String loserDeckName, Date startDate, Date endDate); - public List getGameHistoryForPlayer(Player player, int start, int count); + public List getGameHistoryForPlayer(Player player, int start, int count); public int getGameHistoryForPlayerCount(Player player); - public List getGameHistoryForFormat(String format, int count); + public List getGameHistoryForFormat(String format, int count); public int getActivePlayersCount(long from, long duration); @@ -26,5 +26,5 @@ public interface GameHistoryDAO { public List getCompetitivePlayerStatistics(Player player); - List getLastGames(String formatName, int count); + List getLastGames(String formatName, int count); } diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/vo/GameHistoryEntry.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/vo/GameHistoryEntry.java index 9a2bf83e3..fd62d7584 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/vo/GameHistoryEntry.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/vo/GameHistoryEntry.java @@ -2,39 +2,4 @@ package com.gempukku.lotro.db.vo; import java.util.Date; -public class GameHistoryEntry { - public int id; - - public String winner; - public String loser; - - public String win_reason; - public String lose_reason; - - public String win_recording_id; - public String lose_recording_id; - - public long start_date; - public long end_date; - - public String format_name; - - public String winner_deck_name; - public String loser_deck_name; - - public String tournament; - - - public Date GetStartDate() - { - return new Date(start_date); - } - - public Date GetEndDate() - { - return new Date(end_date); - } - - -} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/CompleteCardCollection.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/CompleteCardCollection.java new file mode 100644 index 000000000..7c3165e15 --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/CompleteCardCollection.java @@ -0,0 +1,54 @@ +package com.gempukku.lotro.game; + +import com.gempukku.lotro.common.CardType; + +import java.util.Collections; +import java.util.Map; +import java.util.stream.Collectors; + +public class CompleteCardCollection implements CardCollection { + + private final LotroCardBlueprintLibrary _library; + + public CompleteCardCollection(LotroCardBlueprintLibrary library) { + _library = library; + } + @Override + public int getCurrency() { + return 0; + } + + @Override + public Iterable getAll() { + return _library.getBaseCards().entrySet().stream().map(cardBlueprintEntry -> { + String blueprintId = cardBlueprintEntry.getKey(); + int count = getCount(cardBlueprintEntry.getValue()); + return Item.createItem(blueprintId, count); + }).collect(Collectors.toList()); + } + + @Override + public int getItemCount(String blueprintId) { + final String baseBlueprintId = _library.getBaseBlueprintId(blueprintId); + if (baseBlueprintId.equals(blueprintId)) { + try { + return getCount(_library.getLotroCardBlueprint(blueprintId)); + } catch (CardNotFoundException exp) { + return 0; + } + } + return 0; + } + + private int getCount(LotroCardBlueprint blueprint) { + final CardType cardType = blueprint.getCardType(); + if (cardType == CardType.SITE || cardType == CardType.THE_ONE_RING) + return 1; + return 4; + } + + @Override + public Map getExtraInformation() { + return Collections.emptyMap(); + } +} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/DefaultCardCollection.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/DefaultCardCollection.java index 763413dcc..0bd770cda 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/DefaultCardCollection.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/DefaultCardCollection.java @@ -1,25 +1,24 @@ package com.gempukku.lotro.game; -import com.gempukku.lotro.packs.PacksStorage; import com.gempukku.lotro.packs.ProductLibrary; import java.util.*; public class DefaultCardCollection implements MutableCardCollection { + public static String CurrencyKey = "currency"; private final Map _counts = new LinkedHashMap<>(); - private int _currency; private Map _extraInformation = new HashMap<>(); public DefaultCardCollection() { - + _extraInformation.put(CurrencyKey, 0); } public DefaultCardCollection(CardCollection cardCollection) { + this(); for (Item item : cardCollection.getAll()) { _counts.put(item.getBlueprintId(), item); } - _currency = cardCollection.getCurrency(); _extraInformation.putAll(cardCollection.getExtraInformation()); } @@ -34,20 +33,23 @@ public class DefaultCardCollection implements MutableCardCollection { @Override public synchronized void addCurrency(int currency) { - _currency += currency; + int oldCurrency = (Integer) _extraInformation.get(CurrencyKey); + _extraInformation.put(CurrencyKey, oldCurrency + currency); } @Override public synchronized boolean removeCurrency(int currency) { - if (_currency < currency) + int oldCurrency = (Integer) _extraInformation.get(CurrencyKey); + + if (oldCurrency < currency) return false; - _currency -= currency; + _extraInformation.put(CurrencyKey, oldCurrency - currency); return true; } @Override public synchronized int getCurrency() { - return _currency; + return (Integer) _extraInformation.get(CurrencyKey); } @Override diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GameHistoryService.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GameHistoryService.java index 0d4ceb597..d271074d7 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GameHistoryService.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/GameHistoryService.java @@ -1,8 +1,8 @@ package com.gempukku.lotro.game; +import com.gempukku.lotro.common.DBDefs; import com.gempukku.lotro.db.GameHistoryDAO; import com.gempukku.lotro.db.PlayerStatistic; -import com.gempukku.lotro.db.vo.GameHistoryEntry; import java.util.Date; import java.util.List; @@ -36,15 +36,15 @@ public class GameHistoryService { return count; } - public List getGameHistoryForPlayer(Player player, int start, int count) { + public List getGameHistoryForPlayer(Player player, int start, int count) { return _gameHistoryDAO.getGameHistoryForPlayer(player, start, count); } - public List getGameHistoryForFormat(String format, int count) { + public List getGameHistoryForFormat(String format, int count) { return _gameHistoryDAO.getGameHistoryForFormat(format, count); } - public List getTrackableGames(int count) { + public List getTrackableGames(int count) { return _gameHistoryDAO.getLastGames("Second Edition", count); } diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTestHelper.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTestHelper.java index d3b578adf..8d91f2797 100644 --- a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTestHelper.java +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/cards/GenericCardTestHelper.java @@ -296,11 +296,14 @@ public class GenericCardTestHelper extends AbstractAtTest { public int GetFreepsArcheryTotal() { return RuleUtils.calculateFellowshipArcheryTotal(_game); } public int GetShadowArcheryTotal() { return RuleUtils.calculateShadowArcheryTotal(_game); } - public int GetFreepsHandCount() { return GetPlayerHandCount(P1); } - public int GetShadowHandCount() { return GetPlayerHandCount(P2); } - public int GetPlayerHandCount(String player) + public int GetFreepsHandCount() { return GetFreepsHand().size(); } + public int GetShadowHandCount() { return GetShadowHand().size(); } + + public List GetFreepsHand() { return GetPlayerHand(P1); } + public List GetShadowHand() { return GetPlayerHand(P2); } + public List GetPlayerHand(String player) { - return _game.getGameState().getHand(player).size(); + return _game.getGameState().getHand(player); } public int GetFreepsDeckCount() { return GetPlayerDeckCount(P1); } @@ -421,6 +424,14 @@ public class GenericCardTestHelper extends AbstractAtTest { }); } + public void FreepsDrawCard() { + _game.getGameState().playerDrawsCard(P1); + } + + public void ShadowDrawCard() { + _game.getGameState().playerDrawsCard(P2); + } + public void FreepsShuffleCardsInDeck(String...cardNames) { Arrays.stream(cardNames).forEach(cardName -> FreepsShuffleCardsInDeck(GetFreepsCard(cardName))); }
" + dateFormat.format(new Date(gameHistoryEntry.GetStartDate().getTime())) + "" + dateFormat.format(new Date(gameHistoryEntry.GetEndDate().getTime())) + "" + gameHistoryEntry.winner + "" + gameHistoryEntry.win_reason + "" + gameHistoryEntry.winner_deck_name + "Replay" + dateFormat.format(new Date(game.GetStartDate().getTime())) + "" + dateFormat.format(new Date(game.GetEndDate().getTime())) + "" + game.winner + "" + game.win_reason + "" + game.winner_deck_name + "Replay
" + gameHistoryEntry.loser + "" + gameHistoryEntry.lose_reason + "" + gameHistoryEntry.lose_reason + "Replay" + game.loser + "" + game.lose_reason + "" + game.lose_reason + "Replay