package forge; import forge.Card; import forge.card.trigger.TriggerHandler; import forge.error.ErrorViewer; import forge.properties.NewConstants; import java.io.*; import java.util.Enumeration; import java.util.Map; import java.util.StringTokenizer; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import com.google.code.jyield.YieldUtils; import net.slightlymagic.braids.util.generator.FindNonDirectoriesSkipDotDirectoriesGenerator; import net.slightlymagic.braids.util.generator.GeneratorFunctions; import forge.gui.MultiPhaseProgressMonitorWithETA; /** * <p>ReadCard class.</p> * * @author Forge * @version $Id: $ */ public class ReadCard implements Runnable, NewConstants { private BufferedReader in; Map<String,Card> mapToFill; private File cardsfolder; private File zipFile; /** * <p>getCards.</p> * * @deprected This isn't being used by anything, so it has been commented out; * future revisions may delete this method. * * @return a {@link java.util.ArrayList} object. */ //public ArrayList<Card> getCards() { // return new ArrayList<Card>(allCards); //} /** * <p>Constructor for ReadCard.</p> * * @deprected This isn't being used by anything, so it has been commented out; * future revisions may delete this method. * * @param filename a {@link java.lang.String} object. */ //public ReadCard(String filename) { // this(new File(filename)); //} /** * <p>Constructor for ReadCard.</p> * * @param cardsfolder a {@link java.io.File} object. * * @param mapToFill maps card names to Card instances; this is where we place the cards once read * */ public ReadCard(File cardsfolder, Map<String, Card> mapToFill) { if (mapToFill == null) { throw new NullPointerException("mapToFill must not be null."); } this.mapToFill = mapToFill; if (!cardsfolder.exists()) throw new RuntimeException("ReadCard : constructor error -- file not found -- filename is " + cardsfolder.getAbsolutePath()); if (!cardsfolder.isDirectory()) throw new RuntimeException("ReadCard : constructor error -- not a directory -- " + cardsfolder.getAbsolutePath()); zipFile = new File(cardsfolder, CARDSFOLDER + ".zip"); this.cardsfolder = cardsfolder; }//ReadCard() /** * <p>run.</p> * @since 1.0.15 */ public void run() { Card c = null; if (zipFile.exists()) { try { ZipFile zip = new ZipFile(zipFile); ZipEntry entry; int zipSize = zip.size(); MultiPhaseProgressMonitorWithETA monitor = new MultiPhaseProgressMonitorWithETA("Forge - Loading card database from ZIP", 1, zipSize, 1.0f); Enumeration<? extends ZipEntry> e = zip.entries(); while (e.hasMoreElements()) { entry = (ZipEntry) e.nextElement(); if (entry.isDirectory() || !entry.getName().endsWith(".txt")) { monitor.incrementUnitsCompletedThisPhase(1L); continue; } in = new BufferedReader(new InputStreamReader(zip.getInputStream(entry))); c = new Card(); loadCard(c); mapToFill.put(c.getName(), c); in.close(); monitor.incrementUnitsCompletedThisPhase(1L); } monitor.getDialog().dispose(); } catch (Exception e) { } } else { FindNonDirectoriesSkipDotDirectoriesGenerator findNonDirsGen = new FindNonDirectoriesSkipDotDirectoriesGenerator(cardsfolder); long fileCount = GeneratorFunctions.estimateSize(findNonDirsGen); MultiPhaseProgressMonitorWithETA monitor = new MultiPhaseProgressMonitorWithETA("Forge - Loading card database from files", 1, fileCount, 1.0f); for (File cardTxtFile : YieldUtils.toIterable(findNonDirsGen)) { if (!cardTxtFile.getName().endsWith(".txt")) { monitor.incrementUnitsCompletedThisPhase(1L); continue; } try { in = new BufferedReader(new FileReader(cardTxtFile)); } catch (Exception ex) { ErrorViewer.showError(ex, "File \"%s\" exception", cardTxtFile.getAbsolutePath()); throw new RuntimeException("ReadCard : run error -- file exception -- filename is " + cardTxtFile.getPath(), ex); } c = new Card(); loadCard(c); mapToFill.put(c.getName(), c); monitor.incrementUnitsCompletedThisPhase(1L); try { in.close(); } catch (IOException ex) { ErrorViewer.showError(ex, "File \"%s\" exception", cardTxtFile.getAbsolutePath()); throw new RuntimeException("ReadCard : run error -- file exception -- filename is " + cardTxtFile.getPath(), ex); } } //endfor monitor.getDialog().dispose(); } //endif }//run() /** * <p>addTypes.</p> * * @param c a {@link forge.Card} object. * @param types a {@link java.lang.String} object. */ private void addTypes(Card c, String types) { StringTokenizer tok = new StringTokenizer(types); while (tok.hasMoreTokens()) c.addType(tok.nextToken()); } /** * <p>readLine.</p> * * @return a {@link java.lang.String} object. * @param in a {@link java.io.BufferedReader} object. */ private String readLine() { //makes the checked exception, into an unchecked runtime exception try { String s = in.readLine(); if (s != null) s = s.trim(); return s; } catch (Exception ex) { ErrorViewer.showError(ex); throw new RuntimeException("ReadCard : readLine(Card) error", ex); } }//readLine(Card) /** * <p>loadCard.</p> * * @param c a {@link forge.Card} object. */ private void loadCard(Card c) { String s = readLine(); while (!s.equals("End")) { if (s.startsWith("#")) { //no need to do anything, this indicates a comment line } else if (s.startsWith("Name:")) { String t = s.substring(5); //if (Constant.Runtime.DevMode[0]) // System.out.println("ReadCard: " + s); if (mapToFill.containsKey(t)) { System.out.println("ReadCard:run() error - duplicate card name: " + t); throw new RuntimeException("ReadCard:run() error - duplicate card name: " + t); } else c.setName(t); } else if (s.startsWith("ManaCost:")) { String t = s.substring(9); //System.out.println(s); if (!t.equals("no cost")) c.setManaCost(t); } else if (s.startsWith("Types:")) addTypes(c, s.substring(6)); else if (s.startsWith("Text:")) { String t = s.substring(5); // if (!t.equals("no text")); if (t.equals("no text")) t = (""); c.setText(t); } else if (s.startsWith("PT:")) { String t = s.substring(3); String pt[] = t.split("/"); int att = pt[0].contains("*") ? 0 : Integer.parseInt(pt[0]); int def = pt[1].contains("*") ? 0 : Integer.parseInt(pt[1]); c.setBaseAttackString(pt[0]); c.setBaseDefenseString(pt[1]); c.setBaseAttack(att); c.setBaseDefense(def); } else if (s.startsWith("Loyalty:")) { String splitStr[] = s.split(":"); int loyal = Integer.parseInt(splitStr[1]); c.setBaseLoyalty(loyal); } else if (s.startsWith("K:")) { String t = s.substring(2); c.addIntrinsicKeyword(t); } else if (s.startsWith("SVar:")) { String t[] = s.split(":", 3); c.setSVar(t[1], t[2]); } else if (s.startsWith("A:")) { String t = s.substring(2); c.addIntrinsicAbility(t); } else if (s.startsWith("T:")) { String t = s.substring(2); c.addTrigger(TriggerHandler.parseTrigger(t, c)); } else if (s.startsWith("S:")) { String t = s.substring(2); c.addStaticAbilityString(t); } else if (s.startsWith("SetInfo:")) { String t = s.substring(8); c.addSet(new SetInfo(t)); } s = readLine(); } // while !End } }