package org.kjtw.main; import java.awt.Cursor; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.*; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import javax.imageio.ImageIO; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.SwingWorker; import org.kjtw.process.SRFProcess; import org.kjtw.resources.YDKJPalettes; import org.kjtw.structures.CCCOut; import org.kjtw.structures.DisorDatOut; import org.kjtw.structures.FiberOpticOut; import org.kjtw.structures.FillintheBlankOut; import org.kjtw.structures.GameTemplate; import org.kjtw.structures.GibberishOut; import org.kjtw.structures.GuestHostQuestionOut; import org.kjtw.structures.JackAttackOut; import org.kjtw.structures.JackGraphic; import org.kjtw.structures.PictureQuestionOut; import org.kjtw.structures.QHeader; import org.kjtw.structures.QHeaderout; import org.kjtw.structures.ShortieQuestionOut; import org.kjtw.structures.SuperAudioQuestionout; import org.kjtw.structures.ThreeWayOut; import org.kjtw.structures.WhatshisnameOut; import org.kjtw.structures.YDKJQ; import com.google.gson.Gson; import com.kreative.ksfl.KSFLUtilities; import com.kreative.rsrc.BerkeleyResourceFile; import com.kreative.rsrc.MacResource; import com.kreative.rsrc.MacResourceFile; import com.kreative.rsrc.SoundResource; import javax.swing.JProgressBar; import javax.swing.JComboBox; public class BatchProcessor extends JPanel implements ActionListener, PropertyChangeListener { private JButton startButton; private JTextArea taskOutput; private Task task; private JLabel lblPaletteusEngine; private JButton button; private static String dirin; private static String dirout; private String pal; private JProgressBar progressBar; static ArrayList<String> fileNames; static ArrayList<String> qhnames; static ArrayList<QHeader> qheads; private JComboBox comboBox; class Task extends SwingWorker<Void, Void> { /* * Main task. Executed in background thread. */ @Override public Void doInBackground() { fileNames.clear(); qhnames.clear(); qheads.clear(); ExecutorService es = Executors.newFixedThreadPool(10); taskOutput.append("Scanning for files\n"); Path in = Paths.get(dirin); getFileNames(in); int progress = 0; int total = fileNames.size(); //Initialize progress property. setProgress(progress/total); // taskOutput.append("Processing "+total+"files\n"); taskOutput.append("Processing question data\n"); for (final String file : qhnames) { es.submit(new Runnable() { public void run() { procq(file); } }); // progress++; // setProgress(progress/total); } es.shutdown(); try { es.awaitTermination(1, TimeUnit.HOURS); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } taskOutput.append("Processing "+qheads.size()+"questions\n"); for (final QHeader qh: qheads) { es.submit(new Runnable() { public void run() { try { QHProc(qh); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); // progress++; // setProgress(progress/total); } for (final String file : fileNames) { es.submit(new Runnable() { public void run() { procfile(file); } }); // progress++; // setProgress(progress/total); } es.shutdown(); try { es.awaitTermination(1, TimeUnit.HOURS); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } es.shutdown(); try { es.awaitTermination(1, TimeUnit.HOURS); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } protected void procq(String file) { taskOutput.append("Processing file"+file+"\n"); File f = new File(file); SRFProcess srfp = null; try { srfp = new SRFProcess(f); } catch (IOException e) { taskOutput.append("Error detected with "+file+" processing, may not be fatal, carrying on\n"); } String suff = file.replace(dirin, ""); suff = suff.substring(0, suff.length()-4); String out = dirout + File.separator +suff; try { QSave(out, srfp,f); } catch (Exception e) { // TODO Auto-generated catch block taskOutput.append("Error detected with "+file+" saving, may not be fatal, carrying on\n"); } taskOutput.append(file+"complete\n"); } private void QSave(String out, SRFProcess srfp, File f) { Hashtable<String, byte[]> data = srfp.getData(); Hashtable<String, String> parents = srfp.getParents(); BerkeleyResourceFile rp = srfp.getBRF(); Enumeration<String> enumKey = data.keys(); List<QHeaderout> qh = new ArrayList<QHeaderout>(); boolean firstpass=true; while(enumKey.hasMoreElements()) { String key = enumKey.nextElement(); String nametype = key.substring(0, key.indexOf('_')); int ftype = KSFLUtilities.fcc(nametype); File typedir = new File (dirout+File.separator+nametype); String type = parents.get(nametype); typedir.mkdirs(); if (type.equals("qheader")) { if (firstpass ==true) { int ftypex = KSFLUtilities.fcc("qhdr"); for (int id2 : rp.getfullIDs(ftype)) { MacResource r = rp.getFromFullID(ftypex, id2); QHeader qh1 = new QHeader(id2,r.data,f); qh.add(new QHeaderout (qh1,true)); qheads.add(qh1); } firstpass = false; } } } if (qh.size() > 0) { try { File output = new File(dirout, ".json"); if (!output.exists()) { output.createNewFile(); Gson gson = new Gson(); String json = gson.toJson(qh); PrintWriter pout = new PrintWriter(output); pout.print(json); pout.close(); } } catch (IOException e) { System.err.println("Error: Cannot write file ("+e.getClass().getSimpleName()+": "+e.getMessage()+")"); } } } protected void procfile(String file) { taskOutput.append("Processing file"+file+"\n"); File f = new File(file); SRFProcess srfp = null; try { srfp = new SRFProcess(f); } catch (IOException e) { taskOutput.append("Error detected with "+file+" processing, may not be fatal, carrying on\n"); } String suff = file.replace(dirin, ""); suff = suff.substring(0, suff.length()-4); String out = dirout + File.separator +suff; try { SRFSave(out, srfp,f); } catch (Exception e) { // TODO Auto-generated catch block taskOutput.append("Error detected with "+file+" saving, may not be fatal, carrying on\n"); } taskOutput.append(file+"complete\n"); } /* * Executed in event dispatching thread */ @Override public void done() { Toolkit.getDefaultToolkit().beep(); startButton.setEnabled(true); setCursor(null); //turn off the wait cursor taskOutput.append("Done!\n"); } } public BatchProcessor() { GridBagLayout gridBagLayout = new GridBagLayout(); gridBagLayout.columnWidths = new int[]{116, 58, 0, 0, 0, 0, 0, 0, 0}; gridBagLayout.rowHeights = new int[]{33, 0, 227, 0}; gridBagLayout.columnWeights = new double[]{0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE}; gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE}; setLayout(gridBagLayout); lblPaletteusEngine = new JLabel("Palette"); GridBagConstraints gbc_lblPaletteusEngine = new GridBagConstraints(); gbc_lblPaletteusEngine.insets = new Insets(0, 0, 5, 5); gbc_lblPaletteusEngine.gridx = 0; gbc_lblPaletteusEngine.gridy = 0; add(lblPaletteusEngine, gbc_lblPaletteusEngine); button = new JButton("Input Directory"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { SetInDirectory(); } }); String[] palettes = { "YDKJ 1", "YDKJ 2", "YDKJ 3", "YDKJ 4 (The Ride)", "HeadRush", "Offline", "Louder! Faster! Funnier!","Movies/TV/Sports" }; comboBox = new JComboBox(palettes); comboBox.setSelectedIndex(1); comboBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { JComboBox cb = (JComboBox)arg0.getSource(); String p = (String)cb.getSelectedItem(); new YDKJPalettes(); pal = YDKJPalettes.getPalettes().get(p); } }); GridBagConstraints gbc_comboBox = new GridBagConstraints(); gbc_comboBox.gridwidth = 6; gbc_comboBox.insets = new Insets(0, 0, 5, 5); gbc_comboBox.fill = GridBagConstraints.HORIZONTAL; gbc_comboBox.gridx = 1; gbc_comboBox.gridy = 0; add(comboBox, gbc_comboBox); GridBagConstraints gbc_button = new GridBagConstraints(); gbc_button.anchor = GridBagConstraints.WEST; gbc_button.insets = new Insets(0, 0, 5, 5); gbc_button.gridx = 0; gbc_button.gridy = 1; add(button, gbc_button); progressBar = new JProgressBar(); GridBagConstraints gbc_progressBar = new GridBagConstraints(); gbc_progressBar.fill = GridBagConstraints.HORIZONTAL; gbc_progressBar.gridwidth = 6; gbc_progressBar.insets = new Insets(0, 0, 5, 5); gbc_progressBar.gridx = 1; gbc_progressBar.gridy = 1; add(progressBar, gbc_progressBar); //Create the demo's UI. startButton = new JButton("Start"); GridBagConstraints gbc_startButton = new GridBagConstraints(); gbc_startButton.insets = new Insets(0, 0, 5, 0); gbc_startButton.gridx = 7; gbc_startButton.gridy = 1; add(startButton, gbc_startButton); startButton.setActionCommand("start"); startButton.addActionListener(this); taskOutput = new JTextArea(5, 20); taskOutput.setMargin(new Insets(5,5,5,5)); taskOutput.setEditable(false); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = 8; gbc.fill = GridBagConstraints.BOTH; gbc.gridx = 0; gbc.gridy = 2; JScrollPane scrollPane = new JScrollPane(taskOutput); add(scrollPane, gbc); setBorder(null); } public void QHProc(QHeader qh) throws IOException { taskOutput.append("Processing Question"+qh.getName()+"\n"); File f = new File(qh.getPath()); String suff = f.getAbsolutePath().replace(dirin, ""); suff = suff.substring(0, suff.length()-4); String wout = dirout + File.separator +suff; Gson gson = new Gson(); YDKJQ q=null; switch (qh.getType()) { case 0: { switch (qh.getSubType()) { case 1: { q = new ShortieQuestionOut(wout,qh); break; } case 2: { q = new FillintheBlankOut(wout,qh); break; } case 3: { q = new WhatshisnameOut(wout,qh); break; } case 4: { q = new PictureQuestionOut(wout, qh,pal); break; } case 5: { q = new SuperAudioQuestionout(wout,qh); break; } case 6: { q = new GuestHostQuestionOut(wout,qh,pal); } } break; } case 1: { break; } case 2: { q = new GibberishOut(wout,qh); break; } case 3: { q = new DisorDatOut(wout,qh); break; } case 4: { q = new JackAttackOut(wout,qh); break; } case 5: { q = new FiberOpticOut(wout,qh); break; } case 10: { q = new CCCOut(wout,qh,pal); break; } case 12: { q = new ThreeWayOut(wout,qh); break; } } try { File output = new File(wout, qh.getName()+".json"); output.createNewFile(); PrintWriter out = new PrintWriter(output); out.print(gson.toJson(q)); out.close(); } catch (IOException e) { System.err.println("Error: Cannot write file ("+e.getClass().getSimpleName()+": "+e.getMessage()+")"); } fileNames.remove(qh.getPath()); taskOutput.append(qh.getName()+"complete\n"); } protected static void SetInDirectory() { String indir=""; if (dirin == null) { indir="C:\\ydkj"; } else { indir=dirin; } JFileChooser chooser = new JFileChooser(indir); chooser.setDialogTitle("Select the root directory (containing the _CD file)"); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.showOpenDialog(null); dirin = chooser.getSelectedFile().getPath(); } protected static void SetOutDirectory() { String outdir=""; if (dirout == null) { outdir="C:\\ydkj"; } else { outdir=dirin; } JFileChooser chooser = new JFileChooser(outdir); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.showOpenDialog(null); dirout = chooser.getSelectedFile().getPath(); } /** * Invoked when the user presses the start button. */ public void actionPerformed(ActionEvent evt) { if (evt.getActionCommand().equals("start")) { startButton.setEnabled(false); SetOutDirectory(); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); //Instances of javax.swing.SwingWorker are not reusuable, so //we create new instances as needed. task = new Task(); task.addPropertyChangeListener(this); task.execute(); } else { pal = evt.getActionCommand(); } } /** * Invoked when task's progress property changes. */ public void propertyChange(PropertyChangeEvent evt) { if ("progress" == evt.getPropertyName()) { int progress = (Integer) evt.getNewValue(); progressBar.setValue(progress); taskOutput.append(String.format( "Completed %d%% of task.\n", task.getProgress())); } } /** * Create the GUI and show it. As with all GUI code, this must run * on the event-dispatching thread. */ private static void createAndShowGUI() { //Create and set up the window. JFrame frame = new JFrame("BatchProcessor"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. JComponent newContentPane = new BatchProcessor(); fileNames = new ArrayList<String>(); qhnames = new ArrayList<String>(); qheads = new ArrayList<QHeader>(); newContentPane.setOpaque(true); //content panes must be opaque frame.setContentPane(newContentPane); //Display the window. frame.pack(); frame.setVisible(true); } private List<String> getFileNames(Path dir){ try { DirectoryStream<Path> stream = Files.newDirectoryStream(dir); for (Path path : stream) { if(path.toFile().isDirectory()) { getFileNames(path); } else { if (path.getFileName().toString().toLowerCase().contains(".srf")) { String p = path.toAbsolutePath().toString(); File f = new File(p); BerkeleyResourceFile rp = null; try { rp = new BerkeleyResourceFile(f, "r", MacResourceFile.CREATE_NEVER); } catch (IOException e) { System.err.println("Error: Invalid file ("+e.getClass().getSimpleName()+": "+e.getMessage()+")"); } boolean qhead=false; for (int type : rp.getTypes()) { String ftype = KSFLUtilities.fccs(type).trim(); if (ftype.equals("qhdr")) { qhnames.add(p); qhead=true; } } if (qhead == false) { fileNames.add(p); } } } } stream.close(); }catch(IOException e){ e.printStackTrace(); } return fileNames; } protected void SRFSave(String dirout, SRFProcess srfp, File f) throws Exception{ Hashtable<String, byte[]> data = srfp.getData(); Hashtable<String, String> parents = srfp.getParents(); BerkeleyResourceFile rp = srfp.getBRF(); Enumeration<String> enumKey = data.keys(); List<QHeaderout> qh = new ArrayList<QHeaderout>(); List<QHeaderout> qh2 = new ArrayList<QHeaderout>(); boolean firstpass=true; while(enumKey.hasMoreElements()) { String key = enumKey.nextElement(); String nametype = key.substring(0, key.indexOf('_')); int ftype = KSFLUtilities.fcc(nametype); File typedir = new File (dirout+File.separator+nametype); String type = parents.get(nametype); String suffix=""; byte[] val = null; String id = key.substring(key.indexOf('_')+1); typedir.mkdirs(); if (type.equals("audio")) { MacResource r = rp.get(ftype, Short.parseShort(id)); SoundResource rsnd = r.shallowRecast(SoundResource.class); try { File output = new File(typedir, id+".wav"); output.createNewFile(); FileOutputStream fos = new FileOutputStream(output); fos.write(rsnd.toWav()); fos.close(); } catch (IOException e) { System.err.println("Error: Cannot write file ("+e.getClass().getSimpleName()+": "+e.getMessage()+")"); } } else if (type.equals("gfx")) { MacResource r = rp.get(ftype, Short.parseShort(id)); JackGraphic jgfx = new JackGraphic(r.data); jgfx.SetPalette(pal); File outputimage = new File(typedir, id+".gif"); try { ImageIO.write(jgfx.toGif(jgfx.GetPalette()), "gif", outputimage); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try { File output = new File(typedir, id+".json"); output.createNewFile(); PrintWriter out = new PrintWriter(output); out.print(jgfx.getTileJSON()); out.print(jgfx.getFrameJSON()); out.close(); } catch (IOException e) { System.err.println("Error: Cannot write file ("+e.getClass().getSimpleName()+": "+e.getMessage()+")"); } } else if (type.equals("template")) { List<GameTemplate>gt = new ArrayList<GameTemplate>(); for (short id2 : rp.getIDs(ftype)) { MacResource r = rp.get(ftype, (short) id2); gt.add(new GameTemplate(r.data)); } try { File output = new File(typedir, nametype+".json"); if (!output.exists()) { output.createNewFile(); Gson gson = new Gson(); String json = gson.toJson(gt); PrintWriter out = new PrintWriter(output); out.print(json); out.close(); } } catch (IOException e) { System.err.println("Error: Cannot write file ("+e.getClass().getSimpleName()+": "+e.getMessage()+")"); } } else if (type.equals("qheader")) { if (firstpass ==true) { int ftypex = KSFLUtilities.fcc("qhdr"); for (int id2 : rp.getfullIDs(ftype)) { MacResource r = rp.getFromFullID(ftypex, id2); QHeader qh1 = new QHeader(id2,r.data,f); qh.add(new QHeaderout (qh1,true)); qheads.add(qh1); qh2.add(new QHeaderout (qh1,false)); } firstpass = false; } } else { val = data.get(key); suffix=".txt"; } if (val != null) { try { File output = new File(typedir, id+suffix); output.createNewFile(); FileOutputStream fos = new FileOutputStream(output); fos.write(val); fos.close(); } catch (IOException e) { System.err.println("Error: Cannot write file ("+e.getClass().getSimpleName()+": "+e.getMessage()+")"); } } } if (qh.size() > 0) { try { File output = new File(dirout, ".json"); if (!output.exists()) { output.createNewFile(); Gson gson = new Gson(); String json = gson.toJson(qh); PrintWriter out = new PrintWriter(output); out.print(json); out.close(); } } catch (IOException e) { System.err.println("Error: Cannot write file ("+e.getClass().getSimpleName()+": "+e.getMessage()+")"); } try { File output = new File(dirout, "J.json"); if (!output.exists()) { output.createNewFile(); Gson gson = new Gson(); String json = gson.toJson(qh2); PrintWriter out = new PrintWriter(output); out.print(json); out.close(); } } catch (IOException e) { System.err.println("Error: Cannot write file ("+e.getClass().getSimpleName()+": "+e.getMessage()+")"); } } } public static void main(String[] args) { //Schedule a job for the event-dispatching thread: //creating and showing this application's GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { SetInDirectory(); createAndShowGUI(); } }); } }