From bdafbf4d2a785d167c5e9c7c5a58112f51e76501 Mon Sep 17 00:00:00 2001 From: "marcins78@gmail.com" Date: Wed, 21 Sep 2011 17:35:28 +0000 Subject: [PATCH] Collection serialization. --- .../lotro/cards/packs/RarityReader.java | 41 +++--- gemp-lotr/gemp-lotr-server/pom.xml | 2 +- .../collection/CollectionSerializer.java | 132 ++++++++++++++++++ .../java/com/gempukku/lotro/db/vo/Deck.java | 33 ----- .../gempukku/lotro/game/CardCollection.java | 2 + .../lotro/game/DefaultCardCollection.java | 58 ++++++-- .../src/main/resources/packs.txt | 2 + .../collection/CollectionSerializerTest.java | 42 ++++++ 8 files changed, 251 insertions(+), 61 deletions(-) create mode 100644 gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/collection/CollectionSerializer.java delete mode 100644 gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/vo/Deck.java create mode 100644 gemp-lotr/gemp-lotr-server/src/main/resources/packs.txt create mode 100644 gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/collection/CollectionSerializerTest.java diff --git a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/packs/RarityReader.java b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/packs/RarityReader.java index d27783c9c..d174617e4 100644 --- a/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/packs/RarityReader.java +++ b/gemp-lotr/gemp-lotr-cards/src/main/java/com/gempukku/lotro/cards/packs/RarityReader.java @@ -3,7 +3,6 @@ package com.gempukku.lotro.cards.packs; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import java.net.URL; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -12,28 +11,32 @@ import java.util.Map; public class RarityReader { public SetRarity getSetRarity(String setNo) { try { - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(RarityReader.class.getResourceAsStream("/set"+setNo+"-rarity.txt"), "UTF-8")); - String line; - List tengwar = new LinkedList(); - Map> cardsByRarity = new HashMap>(); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(RarityReader.class.getResourceAsStream("/set" + setNo + "-rarity.txt"), "UTF-8")); + try { + String line; + List tengwar = new LinkedList(); + Map> cardsByRarity = new HashMap>(); - while ((line = bufferedReader.readLine()) != null) { - if (line.endsWith("T")) - tengwar.add(line); - else { - if (!line.substring(0, setNo.length()).equals(setNo)) - throw new IllegalStateException("Seems the rarity is for some other set"); - String rarity = line.substring(setNo.length(), setNo.length()+1); - List cards = cardsByRarity.get(rarity); - if (cards == null) { - cards = new LinkedList(); - cardsByRarity.put(rarity, cards); + while ((line = bufferedReader.readLine()) != null) { + if (line.endsWith("T")) + tengwar.add(line); + else { + if (!line.substring(0, setNo.length()).equals(setNo)) + throw new IllegalStateException("Seems the rarity is for some other set"); + String rarity = line.substring(setNo.length(), setNo.length() + 1); + List cards = cardsByRarity.get(rarity); + if (cards == null) { + cards = new LinkedList(); + cardsByRarity.put(rarity, cards); + } + cards.add(line); } - cards.add(line); } - } - return new DefaultSetRarity(tengwar, cardsByRarity); + return new DefaultSetRarity(tengwar, cardsByRarity); + } finally { + bufferedReader.close(); + } } catch (IOException exp) { throw new RuntimeException("Problem loading rarity of set " + setNo, exp); } diff --git a/gemp-lotr/gemp-lotr-server/pom.xml b/gemp-lotr/gemp-lotr-server/pom.xml index 004d4ec15..cc8058ef1 100644 --- a/gemp-lotr/gemp-lotr-server/pom.xml +++ b/gemp-lotr/gemp-lotr-server/pom.xml @@ -39,7 +39,7 @@ junit junit - 3.8.2 + 4.9 test diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/collection/CollectionSerializer.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/collection/CollectionSerializer.java new file mode 100644 index 000000000..d72d0aa64 --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/collection/CollectionSerializer.java @@ -0,0 +1,132 @@ +package com.gempukku.lotro.collection; + +import com.gempukku.lotro.game.CardCollection; +import com.gempukku.lotro.game.DefaultCardCollection; +import com.gempukku.lotro.game.LotroCardBlueprintLibrary; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class CollectionSerializer { + private List _packIds = new ArrayList(); + private List _cardIds = new ArrayList(); + private LotroCardBlueprintLibrary _library; + + public CollectionSerializer(LotroCardBlueprintLibrary library) { + _library = library; + try { + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(CollectionSerializer.class.getResourceAsStream("/packs.txt"), "UTF-8")); + try { + String line; + while ((line = bufferedReader.readLine()) != null) + _packIds.add(line); + } finally { + bufferedReader.close(); + } + + loadSet("1"); + } catch (IOException exp) { + throw new RuntimeException("Problem loading collection data", exp); + } + } + + private void loadSet(String setNo) throws IOException { + BufferedReader cardReader = new BufferedReader(new InputStreamReader(CollectionSerializer.class.getResourceAsStream("/set" + setNo + "-rarity.txt"), "UTF-8")); + try { + String line; + + while ((line = cardReader.readLine()) != null) { + if (!line.substring(0, setNo.length()).equals(setNo)) + throw new IllegalStateException("Seems the rarity is for some other set"); + // Normal + _cardIds.add(translateToBlueprintId(line)); + // Foil + _cardIds.add(translateToBlueprintId(line) + "*"); + } + } finally { + cardReader.close(); + } + } + + private String translateToBlueprintId(String rarityString) { + int firstNonDigitIndex = getFirstNonDigitIndex(rarityString); + final String setNo = rarityString.substring(0, firstNonDigitIndex); + final String cardAfterSetNo = rarityString.substring(firstNonDigitIndex + 1); + + return setNo + "_" + cardAfterSetNo; + } + + private static int getFirstNonDigitIndex(String string) { + final char[] chars = string.toCharArray(); + for (int i = 0; i < chars.length; i++) + if (!Character.isDigit(chars[i])) + return i; + return -1; + } + + public void serializeCollection(CardCollection collection, OutputStream outputStream) throws IOException { + byte version = 0; + outputStream.write(version); + byte packBytes = (byte) _packIds.size(); + outputStream.write(packBytes); + + final Map collectionCounts = collection.getAll(); + for (String packId : _packIds) { + final Integer count = collectionCounts.get(packId); + if (count == null) + outputStream.write(0); + else + outputStream.write(count); + } + + int cardBytes = _cardIds.size(); + outputStream.write((cardBytes >> 8) & 0x000000ff); + outputStream.write(cardBytes & 0x000000ff); + + for (String cardId : _cardIds) { + final Integer count = collectionCounts.get(cardId); + if (count == null) + outputStream.write(0); + else + outputStream.write(count); + } + } + + public CardCollection deserializeCollection(InputStream inputStream) throws IOException { + int version = inputStream.read(); + if (version == 0) { + return deserializeCollectionVer0(new BufferedInputStream(inputStream)); + } else { + throw new IllegalStateException("Unkown version of serialized collection: " + version); + } + } + + private CardCollection deserializeCollectionVer0(BufferedInputStream inputStream) throws IOException { + int packBytes = inputStream.read(); + + DefaultCardCollection collection = new DefaultCardCollection(); + + byte[] packs = new byte[packBytes]; + int read = inputStream.read(packs); + if (read != packBytes) + throw new IllegalStateException("Under-read the packs information"); + for (int i = 0; i < packs.length; i++) + if (packs[i] > 0) + collection.addPacks(_packIds.get(i), packs[i]); + + int cardBytes = (inputStream.read() << 8) + inputStream.read(); + byte[] cards = new byte[cardBytes]; + read = inputStream.read(cards); + if (read != cardBytes) + throw new IllegalArgumentException("Under-read the packs information"); + for (int i = 0; i < cards.length; i++) + if (cards[i] > 0) { + final String blueprintId = _cardIds.get(i); + collection.addCards(blueprintId, _library.getLotroCardBlueprint(blueprintId), cards[i]); + } + + return collection; + } +} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/vo/Deck.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/vo/Deck.java deleted file mode 100644 index 42e9b1b46..000000000 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/db/vo/Deck.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.gempukku.lotro.db.vo; - -import java.util.List; - -public class Deck { - private String _ringBearer; - private String _ring; - private List _sites; - private List _deck; - - public Deck(String ringBearer, String ring, List sites, List deck) { - _ringBearer = ringBearer; - _ring = ring; - _sites = sites; - _deck = deck; - } - - public String getRingBearer() { - return _ringBearer; - } - - public String getRing() { - return _ring; - } - - public List getSites() { - return _sites; - } - - public List getDeck() { - return _deck; - } -} diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/CardCollection.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/CardCollection.java index 89b3ee4c3..951eb052d 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/CardCollection.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/game/CardCollection.java @@ -3,5 +3,7 @@ package com.gempukku.lotro.game; import java.util.Map; public interface CardCollection { + public Map getAll(); + public Map filter(String filter); } 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 0af4791c9..341b00af4 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 @@ -15,6 +15,15 @@ public class DefaultCardCollection implements CardCollection { _cards.put(blueprintId, blueprint); } + public void addPacks(String packId, int count) { + _cardsCount.put(packId, count); + } + + @Override + public Map getAll() { + return Collections.unmodifiableMap(_cardsCount); + } + @Override public Map filter(String filter) { if (filter == null) @@ -30,10 +39,10 @@ public class DefaultCardCollection implements CardCollection { for (Map.Entry stringLotroCardBlueprintEntry : _cards.entrySet()) { String blueprintId = stringLotroCardBlueprintEntry.getKey(); LotroCardBlueprint blueprint = stringLotroCardBlueprintEntry.getValue(); - if (cardTypes == null || cardTypes.contains(blueprint.getCardType())) - if (cultures == null || cultures.contains(blueprint.getCulture())) + if (cardTypes == null || (blueprint != null && cardTypes.contains(blueprint.getCardType()))) + if (cultures == null || (blueprint != null && cultures.contains(blueprint.getCulture()))) if (containsAllKeywords(blueprint, keywords)) - if (siteNumber == null || blueprint.getSiteNumber() == siteNumber.intValue()) + if (siteNumber == null || (blueprint != null && blueprint.getSiteNumber() == siteNumber.intValue())) result.put(blueprintId, _cardsCount.get(blueprintId)); } return result; @@ -49,7 +58,7 @@ public class DefaultCardCollection implements CardCollection { private boolean containsAllKeywords(LotroCardBlueprint blueprint, List keywords) { for (Keyword keyword : keywords) { - if (!blueprint.hasKeyword(keyword)) + if (blueprint == null || !blueprint.hasKeyword(keyword)) return false; } return true; @@ -84,10 +93,43 @@ public class DefaultCardCollection implements CardCollection { public int compare(String o1, String o2) { String[] o1Parts = o1.split("_"); String[] o2Parts = o2.split("_"); - if (o1Parts[0].equals(o2Parts[0])) - return Integer.parseInt(o1Parts[1]) - Integer.parseInt(o2Parts[1]); - else - return Integer.parseInt(o1Parts[0]) - Integer.parseInt(o2Parts[0]); + if (o1Parts[0].equals(o2Parts[0])) { + final int firstNumber = getAvailableNumber(o1Parts[1]); + final int secondNumber = getAvailableNumber(o2Parts[1]); + + if (firstNumber != secondNumber) + return firstNumber - secondNumber; + + return compareSameCardNumber(o1Parts[1], o2Parts[1]); + } else { + return getAvailableNumber(o1Parts[0]) - getAvailableNumber(o2Parts[0]); + } + } + + private int compareSameCardNumber(String card1, String card2) { + if (card1.endsWith("*") && card2.endsWith("*")) + return compareNotFoils(card1.substring(0, card1.length() - 1), card2.substring(0, card2.length() - 1)); + if (card1.endsWith("*")) + return -1; + if (card2.endsWith("*")) + return 1; + return compareNotFoils(card1, card2); + } + + private int compareNotFoils(String card1, String card2) { + return card1.compareTo(card2); + } + + private int getAvailableNumber(String str) { + return Integer.parseInt(str.substring(0, getFirstNonDigitIndex(str))); + } + + private int getFirstNonDigitIndex(String str) { + final char[] chars = str.toCharArray(); + for (int i = 0; i < chars.length; i++) + if (!Character.isDigit(chars[i])) + return i; + return chars.length; } } } diff --git a/gemp-lotr/gemp-lotr-server/src/main/resources/packs.txt b/gemp-lotr/gemp-lotr-server/src/main/resources/packs.txt new file mode 100644 index 000000000..b0b1025a0 --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/resources/packs.txt @@ -0,0 +1,2 @@ +Fellowship of the Ring +FotR - League Starter \ No newline at end of file diff --git a/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/collection/CollectionSerializerTest.java b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/collection/CollectionSerializerTest.java new file mode 100644 index 000000000..48c6aa52d --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/test/java/com/gempukku/lotro/collection/CollectionSerializerTest.java @@ -0,0 +1,42 @@ +package com.gempukku.lotro.collection; + +import com.gempukku.lotro.game.CardCollection; +import com.gempukku.lotro.game.DefaultCardCollection; +import com.gempukku.lotro.game.LotroCardBlueprintLibrary; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Map; + +import static junit.framework.Assert.assertEquals; + +public class CollectionSerializerTest { + @Test + public void testSerializeDeserialize() throws IOException { + DefaultCardCollection collection = new DefaultCardCollection(); + collection.addCards("1_1", null, 2); + collection.addCards("1_231T", null, 3); + collection.addCards("1_23*", null, 3); + collection.addCards("1_237T*", null, 3); + collection.addPacks("Fellowship of the Ring", 2); + + CollectionSerializer serializer = new CollectionSerializer(new LotroCardBlueprintLibrary()); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + serializer.serializeCollection(collection, baos); + + final byte[] bytes = baos.toByteArray(); + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + CardCollection resultCollection = serializer.deserializeCollection(bais); + + final Map result = resultCollection.getAll(); + assertEquals(5, result.size()); + assertEquals(2, (int) result.get("1_1")); + assertEquals(3, (int) result.get("1_231T")); + assertEquals(3, (int) result.get("1_23*")); + assertEquals(3, (int) result.get("1_237T*")); + assertEquals(2, (int) result.get("Fellowship of the Ring")); + } +}