THE MEGA-FORMATTING COMMIT! TABS RULE, SPACES DROOL

This commit is contained in:
Wirlaburla 2024-07-22 18:19:38 -05:00
parent 6e292212fd
commit 408a52512b
15 changed files with 3084 additions and 3093 deletions

View File

@ -26,254 +26,254 @@ import java.io.*;
import java.util.ArrayList;
public class Bert implements ActionListener {
public JFrame frame = new JFrame();
private JPanel frameContainer;
private JButton cancelbtn;
private JButton downloadbtn;
private JCheckBox patchCheck;
private JCheckBox baseCheck;
private JCheckBox hdCheck;
private JCheckBox furyCheck;
private ButtonGroup radios = new ButtonGroup();
public JFrame frame = new JFrame();
private JPanel frameContainer;
private JButton cancelbtn;
private JButton downloadbtn;
private JCheckBox patchCheck;
private JCheckBox baseCheck;
private JCheckBox hdCheck;
private JCheckBox furyCheck;
private ButtonGroup radios = new ButtonGroup();
private JFrame invoker;
private JFrame invoker;
private boolean wilkinsDownloadFinished = false;
private boolean wilkinsDownloadFinished = false;
public Bert(JFrame parent) {
parent.setEnabled(false);
this.invoker = parent;
public Bert(JFrame parent) {
parent.setEnabled(false);
this.invoker = parent;
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
frame.setSize(600, 300); // 1280 800
frame.setTitle("Download Assets");
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(parent);
frame.setAlwaysOnTop(true);
frame.setSize(600, 300); // 1280 800
frame.setTitle("Download Assets");
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(parent);
frame.setAlwaysOnTop(true);
cancelbtn.addActionListener(this);
downloadbtn.addActionListener(this);
cancelbtn.addActionListener(this);
downloadbtn.addActionListener(this);
frame.setIconImage(Main.windowIcon);
frame.setIconImage(Main.windowIcon);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
parent.setEnabled(true);
e.getWindow().dispose();
}
});
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
parent.setEnabled(true);
e.getWindow().dispose();
}
});
if (!new File(Main.inpath + "pkg2zip.exe").exists() || !new File(Main.inpath + "psvpfsparser.exe").exists()) {
JOptionPane.showMessageDialog(frame, "The decryption tool is missing.\nPlease select \"Get Dependencies\" in the Options menu.", "Error", JOptionPane.ERROR_MESSAGE);
invoker.setEnabled(true);
frame.dispose();
}
}
if (!new File(Main.inpath + "pkg2zip.exe").exists() || !new File(Main.inpath + "psvpfsparser.exe").exists()) {
JOptionPane.showMessageDialog(frame, "The decryption tool is missing.\nPlease select \"Get Dependencies\" in the Options menu.", "Error", JOptionPane.ERROR_MESSAGE);
invoker.setEnabled(true);
frame.dispose();
}
}
public boolean reportWhenDownloaded(WilkinsCoffee setup) {
while (frame.isActive() || !wilkinsDownloadFinished) {}
if (wilkinsDownloadFinished) { // intellij please shut the everloving FUCK up DON'T do this again or i will skin you alive
return true;
} else {
return false;
}
}
public boolean reportWhenDownloaded(WilkinsCoffee setup) {
while (frame.isActive() || !wilkinsDownloadFinished) {}
if (wilkinsDownloadFinished) { // intellij please shut the everloving FUCK up DON'T do this again or i will skin you alive
return true;
} else {
return false;
}
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == cancelbtn) {
invoker.setEnabled(true);
frame.dispose();
} else if (actionEvent.getSource() == downloadbtn) {
ArrayList<Main.ArcTarget> arcs = new ArrayList<Main.ArcTarget>();
ArrayList<Main.ArcKey> keys = new ArrayList<Main.ArcKey>();
if (baseCheck.isSelected()) {
arcs.add(Main.ArcTarget.BASE);
keys.add(Main.ArcKey.BASE);
System.out.println("Begin download of data (Game version 1.0)");
}
if (patchCheck.isSelected()) {
arcs.add(Main.ArcTarget.LATEST);
keys.add(Main.ArcKey.LATEST);
System.out.println("Begin download of data2 (Game version 1.04)");
}
if (hdCheck.isSelected()) {
arcs.add(Main.ArcTarget.ADDON_HD);
keys.add(Main.ArcKey.ADDON_HD);
System.out.println("Begin download of dlc1 (HD DLC)");
}
if (furyCheck.isSelected()) {
arcs.add(Main.ArcTarget.ADDON_HD_FURY);
keys.add(Main.ArcKey.ADDON_HD_FURY);
System.out.println("Begin download of dlc2 (Fury DLC)");
}
if (arcs.isEmpty()) {
JOptionPane.showMessageDialog(invoker, "Select one or more asset packs.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == cancelbtn) {
invoker.setEnabled(true);
frame.dispose();
} else if (actionEvent.getSource() == downloadbtn) {
ArrayList<Main.ArcTarget> arcs = new ArrayList<Main.ArcTarget>();
ArrayList<Main.ArcKey> keys = new ArrayList<Main.ArcKey>();
if (baseCheck.isSelected()) {
arcs.add(Main.ArcTarget.BASE);
keys.add(Main.ArcKey.BASE);
System.out.println("Begin download of data (Game version 1.0)");
}
if (patchCheck.isSelected()) {
arcs.add(Main.ArcTarget.LATEST);
keys.add(Main.ArcKey.LATEST);
System.out.println("Begin download of data2 (Game version 1.04)");
}
if (hdCheck.isSelected()) {
arcs.add(Main.ArcTarget.ADDON_HD);
keys.add(Main.ArcKey.ADDON_HD);
System.out.println("Begin download of dlc1 (HD DLC)");
}
if (furyCheck.isSelected()) {
arcs.add(Main.ArcTarget.ADDON_HD_FURY);
keys.add(Main.ArcKey.ADDON_HD_FURY);
System.out.println("Begin download of dlc2 (Fury DLC)");
}
if (arcs.isEmpty()) {
JOptionPane.showMessageDialog(invoker, "Select one or more asset packs.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
frame.dispose();
invoker.setVisible(false);
frame.dispose();
invoker.setVisible(false);
Thread downloaderPopupThread = new Thread(new Runnable() { // run on separate thread to prevent GUI freezing
@Override
public void run() {
for (Main.ArcTarget type : arcs) {
String key = "";
String arcname = "";
switch (type) {
case BASE :
key = Main.ArcKey.BASE.toString();
arcname = "Base game";
break;
case LATEST :
key = Main.ArcKey.LATEST.toString();
arcname = "Updates";
break;
case ADDON_HD :
key = Main.ArcKey.ADDON_HD.toString();
arcname = "HD Add-On Pack";
break;
case ADDON_HD_FURY :
key = Main.ArcKey.ADDON_HD_FURY.toString();
arcname = "Fury Add-On Pack";
break;
}
if (key.isEmpty()) {
System.out.println("Internal Error: Bert got dementia. Get a programmer!");
JOptionPane.showMessageDialog(invoker, "Internal Error: Bert got dementia. Get a programmer!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
return;
}
Thread downloaderPopupThread = new Thread(new Runnable() { // run on separate thread to prevent GUI freezing
@Override
public void run() {
for (Main.ArcTarget type : arcs) {
String key = "";
String arcname = "";
switch (type) {
case BASE :
key = Main.ArcKey.BASE.toString();
arcname = "Base game";
break;
case LATEST :
key = Main.ArcKey.LATEST.toString();
arcname = "Updates";
break;
case ADDON_HD :
key = Main.ArcKey.ADDON_HD.toString();
arcname = "HD Add-On Pack";
break;
case ADDON_HD_FURY :
key = Main.ArcKey.ADDON_HD_FURY.toString();
arcname = "Fury Add-On Pack";
break;
}
if (key.isEmpty()) {
System.out.println("Internal Error: Bert got dementia. Get a programmer!");
JOptionPane.showMessageDialog(invoker, "Internal Error: Bert got dementia. Get a programmer!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
return;
}
// download file
Fozzie downloaderHandler = new Fozzie();
boolean downloader = downloaderHandler.DownloadFile(type.toString(), Main.inpath, "asset.pkg", arcname);
// download file
Fozzie downloaderHandler = new Fozzie();
boolean downloader = downloaderHandler.DownloadFile(type.toString(), Main.inpath, "asset.pkg", arcname);
if (!downloader) {
// cleanup
new File(Main.inpath + "asset.pkg").delete();
if (!downloader) {
// cleanup
new File(Main.inpath + "asset.pkg").delete();
// restore controls
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
return;
}
// restore controls
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
return;
}
// dump contents
System.out.println("Extracting " + arcname);
Fozzie popup = new Fozzie();
popup.displayTextOnly("Extracting " + arcname + "...", "Extracting");
try {
Process p = Main.exec(new String[]{"pkg2zip.exe", "-x", "asset.pkg", key.toString()}, Main.inpath);
InputStream debugin = new BufferedInputStream(p.getInputStream());
OutputStream debugout = new BufferedOutputStream(System.out);
int c;
while ((c = debugin.read()) != -1) {
debugout.write(c);
}
debugin.close();
debugout.close();
p.waitFor();
} catch (Exception e) {
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(invoker, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
new File(Main.inpath + "asset.pkg").delete();
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
return;
}
// dump contents
System.out.println("Extracting " + arcname);
Fozzie popup = new Fozzie();
popup.displayTextOnly("Extracting " + arcname + "...", "Extracting");
try {
Process p = Main.exec(new String[]{"pkg2zip.exe", "-x", "asset.pkg", key.toString()}, Main.inpath);
InputStream debugin = new BufferedInputStream(p.getInputStream());
OutputStream debugout = new BufferedOutputStream(System.out);
int c;
while ((c = debugin.read()) != -1) {
debugout.write(c);
}
debugin.close();
debugout.close();
p.waitFor();
} catch (Exception e) {
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(invoker, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
new File(Main.inpath + "asset.pkg").delete();
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
return;
}
// decrypt
System.out.println("Decrypting asset.pkg");
String extracted;
String name;
if (type == Main.ArcTarget.BASE) {
extracted = "app/PCSA00015";
name = "data.psarc";
} else if (type == Main.ArcTarget.LATEST) {
extracted = "patch/PCSA00015";
name = "data2.psarc";
} else if (type == Main.ArcTarget.ADDON_HD) {
extracted = "addcont/PCSA00015/DLC1W2048PACKAGE";
name = "dlc1.psarc";
} else if (type == Main.ArcTarget.ADDON_HD_FURY) { // this is not "always true" - intellij is actually very dumj
extracted = "addcont/PCSA00015/DLC2W2048PACKAGE";
name = "dlc2.psarc";
} else {
System.out.println("Internal Error: Bert got dementia. Get a programmer!");
JOptionPane.showMessageDialog(invoker, "Internal Error: Bert got dementia. Get a programmer!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
new File(Main.inpath + "asset.pkg").delete();
Main.deleteDir(new File(Main.inpath + "app/"));
Main.deleteDir(new File(Main.inpath + "patch/"));
Main.deleteDir(new File(Main.inpath + "addcont/"));
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
return;
}
// decrypt
System.out.println("Decrypting asset.pkg");
String extracted;
String name;
if (type == Main.ArcTarget.BASE) {
extracted = "app/PCSA00015";
name = "data.psarc";
} else if (type == Main.ArcTarget.LATEST) {
extracted = "patch/PCSA00015";
name = "data2.psarc";
} else if (type == Main.ArcTarget.ADDON_HD) {
extracted = "addcont/PCSA00015/DLC1W2048PACKAGE";
name = "dlc1.psarc";
} else if (type == Main.ArcTarget.ADDON_HD_FURY) { // this is not "always true" - intellij is actually very dumj
extracted = "addcont/PCSA00015/DLC2W2048PACKAGE";
name = "dlc2.psarc";
} else {
System.out.println("Internal Error: Bert got dementia. Get a programmer!");
JOptionPane.showMessageDialog(invoker, "Internal Error: Bert got dementia. Get a programmer!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
new File(Main.inpath + "asset.pkg").delete();
Main.deleteDir(new File(Main.inpath + "app/"));
Main.deleteDir(new File(Main.inpath + "patch/"));
Main.deleteDir(new File(Main.inpath + "addcont/"));
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
return;
}
popup.setText("<html>Decrypting protected PFS:<br/>" + extracted + "</html>", "Decrypting");
popup.setText("<html>Decrypting protected PFS:<br/>" + extracted + "</html>", "Decrypting");
try {
Process p = Main.exec(new String[]{"psvpfsparser.exe", "-i", extracted, "-o", "./temp/", "-z", key.toString(), "-f", "cma.henkaku.xyz"}, Main.inpath);
InputStream debugin = new BufferedInputStream(p.getInputStream());
OutputStream debugout = new BufferedOutputStream(System.out);
int c;
while ((c = debugin.read()) != -1) {
debugout.write(c);
}
debugin.close();
debugout.close();
p.waitFor();
} catch (Exception e) {
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(invoker, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
new File(Main.inpath + "asset.pkg").delete();
Main.deleteDir(new File(Main.inpath + "app/"));
Main.deleteDir(new File(Main.inpath + "patch/"));
Main.deleteDir(new File(Main.inpath + "addcont/"));
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
return;
}
try {
Process p = Main.exec(new String[]{"psvpfsparser.exe", "-i", extracted, "-o", "./temp/", "-z", key.toString(), "-f", "cma.henkaku.xyz"}, Main.inpath);
InputStream debugin = new BufferedInputStream(p.getInputStream());
OutputStream debugout = new BufferedOutputStream(System.out);
int c;
while ((c = debugin.read()) != -1) {
debugout.write(c);
}
debugin.close();
debugout.close();
p.waitFor();
} catch (Exception e) {
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(invoker, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
new File(Main.inpath + "asset.pkg").delete();
Main.deleteDir(new File(Main.inpath + "app/"));
Main.deleteDir(new File(Main.inpath + "patch/"));
Main.deleteDir(new File(Main.inpath + "addcont/"));
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
return;
}
popup.setText("Deleting temporary files...", "Cleaning Up");
popup.setText("Deleting temporary files...", "Cleaning Up");
// stage & cleanup
System.out.println("Cleaning up");
new File(Main.inpath + "asset.pkg").delete();
new File(Main.inpath + "temp/PSP2/" + name).renameTo(new File(Main.inpath + name));
Main.deleteDir(new File(Main.inpath + "app/"));
Main.deleteDir(new File(Main.inpath + "patch/"));
Main.deleteDir(new File(Main.inpath + "addcont/"));
Main.deleteDir(new File(Main.inpath + "temp/"));
// stage & cleanup
System.out.println("Cleaning up");
new File(Main.inpath + "asset.pkg").delete();
new File(Main.inpath + "temp/PSP2/" + name).renameTo(new File(Main.inpath + name));
Main.deleteDir(new File(Main.inpath + "app/"));
Main.deleteDir(new File(Main.inpath + "patch/"));
Main.deleteDir(new File(Main.inpath + "addcont/"));
Main.deleteDir(new File(Main.inpath + "temp/"));
popup.destroyDialog();
}
popup.destroyDialog();
}
// restore controls
JOptionPane.showMessageDialog(frame, "Assets downloaded successfully.", "Download Complete", JOptionPane.INFORMATION_MESSAGE);
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
wilkinsDownloadFinished = true;
}
});
downloaderPopupThread.start();
}
}
// restore controls
JOptionPane.showMessageDialog(frame, "Assets downloaded successfully.", "Download Complete", JOptionPane.INFORMATION_MESSAGE);
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
wilkinsDownloadFinished = true;
}
});
downloaderPopupThread.start();
}
}
}

View File

@ -33,217 +33,217 @@ import java.util.ArrayList;
import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE;
public class Clifford implements ActionListener {
private JFrame frame = new JFrame();
private JPanel frameContainer;
private JTextField fName;
private JTextField fAuthor;
private JTextField fVersion;
private JTextPane fDescription;
private JButton savebtn;
private JButton cancelbtn;
private JFrame frame = new JFrame();
private JPanel frameContainer;
private JTextField fName;
private JTextField fAuthor;
private JTextField fVersion;
private JTextPane fDescription;
private JButton savebtn;
private JButton cancelbtn;
JFrame invoker;
MissPiggy invokerPig;
boolean isPig = false;
Main.Mod mod;
int index;
File directory;
boolean isSoundtrack = false;
JFrame invoker;
MissPiggy invokerPig;
boolean isPig = false;
Main.Mod mod;
int index;
File directory;
boolean isSoundtrack = false;
boolean creating;
boolean creating;
public void Action(MissPiggy inv, int modindex) {
invokerPig = inv;
invoker = invokerPig.frame;
mod = Main.Mods.get(modindex);
index = modindex;
creating = false;
public void Action(MissPiggy inv, int modindex) {
invokerPig = inv;
invoker = invokerPig.frame;
mod = Main.Mods.get(modindex);
index = modindex;
creating = false;
isPig = true;
isPig = true;
Action(invoker, modindex);
}
Action(invoker, modindex);
}
public void Action(MissPiggy inv, File dir) {
invokerPig = inv;
invoker = invokerPig.frame;
directory = dir;
creating = true;
public void Action(MissPiggy inv, File dir) {
invokerPig = inv;
invoker = invokerPig.frame;
directory = dir;
creating = true;
isPig = true;
isPig = true;
Action(invoker, dir);
}
Action(invoker, dir);
}
public void Action(JFrame inv, int modindex) { // Editor
invoker = inv;
mod = Main.Mods.get(modindex);
index = modindex;
creating = false;
public void Action(JFrame inv, int modindex) { // Editor
invoker = inv;
mod = Main.Mods.get(modindex);
index = modindex;
creating = false;
frame.add(frameContainer);
frame.setIconImage(Main.windowIcon);
frame.setSize(600, 300); // 1280 800
frame.setMinimumSize(new Dimension(200,100));
frame.setTitle("Options");
frame.setResizable(false);
frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(inv);
frame.setAlwaysOnTop(true);
frame.add(frameContainer);
frame.setIconImage(Main.windowIcon);
frame.setSize(600, 300); // 1280 800
frame.setMinimumSize(new Dimension(200,100));
frame.setTitle("Options");
frame.setResizable(false);
frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(inv);
frame.setAlwaysOnTop(true);
fName.setText(mod.friendlyName);
fAuthor.setText(mod.author);
fVersion.setText(String.valueOf(mod.version));
fDescription.setText(mod.description);
fName.setText(mod.friendlyName);
fAuthor.setText(mod.author);
fVersion.setText(String.valueOf(mod.version));
fDescription.setText(mod.description);
cancelbtn.addActionListener(this);
savebtn.addActionListener(this);
cancelbtn.addActionListener(this);
savebtn.addActionListener(this);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
invoker.setEnabled(true);
e.getWindow().dispose();
}
});
}
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
invoker.setEnabled(true);
e.getWindow().dispose();
}
});
}
public void Action(JFrame inv, File dir) { // Generator
invoker = inv;
directory = dir;
creating = true;
public void Action(JFrame inv, File dir) { // Generator
invoker = inv;
directory = dir;
creating = true;
frame.add(frameContainer);
frame.setSize(600, 200); // 1280 800
frame.setMinimumSize(new Dimension(200,100));
frame.setTitle("Options");
frame.setResizable(false);
frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
frame.add(frameContainer);
frame.setSize(600, 200); // 1280 800
frame.setMinimumSize(new Dimension(200,100));
frame.setTitle("Options");
frame.setResizable(false);
frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
cancelbtn.addActionListener(this);
savebtn.addActionListener(this);
cancelbtn.addActionListener(this);
savebtn.addActionListener(this);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
Main.deleteDir(new File(Main.inpath + "temp/")); // soundtrack gen
invoker.setEnabled(true);
e.getWindow().dispose();
}
});
}
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
Main.deleteDir(new File(Main.inpath + "temp/")); // soundtrack gen
invoker.setEnabled(true);
e.getWindow().dispose();
}
});
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == cancelbtn) {
Main.deleteDir(new File(Main.inpath + "temp/")); // soundtrack gen
invoker.setEnabled(true);
frame.dispose();
} else if (actionEvent.getSource() == savebtn && !creating) {
try {
mod.version = Integer.parseInt(fVersion.getText());
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(frame, "Mod version must be a valid integer.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
mod.friendlyName = fName.getText();
mod.author = fAuthor.getText();
mod.description = fDescription.getText();
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == cancelbtn) {
Main.deleteDir(new File(Main.inpath + "temp/")); // soundtrack gen
invoker.setEnabled(true);
frame.dispose();
} else if (actionEvent.getSource() == savebtn && !creating) {
try {
mod.version = Integer.parseInt(fVersion.getText());
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(frame, "Mod version must be a valid integer.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
mod.friendlyName = fName.getText();
mod.author = fAuthor.getText();
mod.description = fDescription.getText();
JSONObject container = new JSONObject();
if (mod.friendlyName.isEmpty()) {
JOptionPane.showMessageDialog(frame, "Mod name cannot be empty.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
container.put("version", mod.version);
container.put("friendlyName", mod.friendlyName);
container.put("author", mod.author);
container.put("description", mod.description);
container.put("loaderversion", mod.loaderversion);
container.put("game", mod.game);
JSONObject container = new JSONObject();
if (mod.friendlyName.isEmpty()) {
JOptionPane.showMessageDialog(frame, "Mod name cannot be empty.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
container.put("version", mod.version);
container.put("friendlyName", mod.friendlyName);
container.put("author", mod.author);
container.put("description", mod.description);
container.put("loaderversion", mod.loaderversion);
container.put("game", mod.game);
try {
new ZipFile(System.getProperty("user.home") + "/.firestar/mods/" + mod.path.trim()).setComment(container.toString());
} catch (ZipException e) {
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(frame, "An error has occured.\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
try {
new ZipFile(System.getProperty("user.home") + "/.firestar/mods/" + mod.path.trim()).setComment(container.toString());
} catch (ZipException e) {
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(frame, "An error has occured.\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
Main.Mods.set(index, mod);
invoker.setEnabled(true);
if (isPig) {invokerPig.InitializeModListInGUI();}
frame.dispose();
} else if (actionEvent.getSource() == savebtn && creating) {
if (fName.getText().isEmpty()) {
JOptionPane.showMessageDialog(frame, "Mod name cannot be empty.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
try {
Integer.parseInt(fVersion.getText());
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(frame, "Mod version must be a valid integer.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
Main.Mods.set(index, mod);
invoker.setEnabled(true);
if (isPig) {invokerPig.InitializeModListInGUI();}
frame.dispose();
} else if (actionEvent.getSource() == savebtn && creating) {
if (fName.getText().isEmpty()) {
JOptionPane.showMessageDialog(frame, "Mod name cannot be empty.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
try {
Integer.parseInt(fVersion.getText());
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(frame, "Mod version must be a valid integer.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileFilter(new FileNameExtensionFilter("Firestar Mod Package", "fstar"));
if (fileChooser.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
ZipFile zip = new ZipFile(fileChooser.getSelectedFile());
boolean hasScript = false;
try {
zip.addFolder(new File(directory.getAbsolutePath() + "/data"));
if (new File(directory.getAbsolutePath() + "/delete.txt").exists()) {
zip.addFile(new File(directory.getAbsolutePath() + "/delete.txt"));
}
if (new File(directory.getAbsolutePath() + "/pack.png").exists()) {
zip.addFile(new File(directory.getAbsolutePath() + "/pack.png"));
}
if (new File(directory.getAbsolutePath() + "/fscript").exists()) {
zip.addFile(new File(directory.getAbsolutePath() + "/fscript"));
hasScript = true;
}
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileFilter(new FileNameExtensionFilter("Firestar Mod Package", "fstar"));
if (fileChooser.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
ZipFile zip = new ZipFile(fileChooser.getSelectedFile());
boolean hasScript = false;
try {
zip.addFolder(new File(directory.getAbsolutePath() + "/data"));
if (new File(directory.getAbsolutePath() + "/delete.txt").exists()) {
zip.addFile(new File(directory.getAbsolutePath() + "/delete.txt"));
}
if (new File(directory.getAbsolutePath() + "/pack.png").exists()) {
zip.addFile(new File(directory.getAbsolutePath() + "/pack.png"));
}
if (new File(directory.getAbsolutePath() + "/fscript").exists()) {
zip.addFile(new File(directory.getAbsolutePath() + "/fscript"));
hasScript = true;
}
JSONObject container = new JSONObject();
container.put("version", Integer.parseInt(fVersion.getText()));
container.put("friendlyName", fName.getText());
container.put("author", fAuthor.getText());
container.put("description", fDescription.getText());
// todo later versions: handle logic for setting this depending on the fscript version too.
// firestar 1.3 can't generate any version other than v1 so this is not necessary right now, but will become necessary when fscript features are added.
if (hasScript) {
container.put("loaderversion", 1);
if (isSoundtrack) {
ArrayList<boolean[]> requiresTemp = new ArrayList<>();
requiresTemp.add(new boolean[]{false, true, false, false});
requiresTemp.add(new boolean[]{true, false, false, false});
container.put("requires", requiresTemp); // Pull localization files for patching.
}
} else {
container.put("loaderversion", 0);
}
container.put("game", "2048");
JSONObject container = new JSONObject();
container.put("version", Integer.parseInt(fVersion.getText()));
container.put("friendlyName", fName.getText());
container.put("author", fAuthor.getText());
container.put("description", fDescription.getText());
// todo later versions: handle logic for setting this depending on the fscript version too.
// firestar 1.3 can't generate any version other than v1 so this is not necessary right now, but will become necessary when fscript features are added.
if (hasScript) {
container.put("loaderversion", 1);
if (isSoundtrack) {
ArrayList<boolean[]> requiresTemp = new ArrayList<>();
requiresTemp.add(new boolean[]{false, true, false, false});
requiresTemp.add(new boolean[]{true, false, false, false});
container.put("requires", requiresTemp); // Pull localization files for patching.
}
} else {
container.put("loaderversion", 0);
}
container.put("game", "2048");
zip.setComment(container.toString());
zip.close();
} catch (Exception e) {
fileChooser.getSelectedFile().delete(); //cleanup
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(frame, "An error has occured.\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
return;
}
JOptionPane.showMessageDialog(frame, "Mod file created", "Success", JOptionPane.INFORMATION_MESSAGE);
Main.deleteDir(new File(Main.inpath + "temp/")); // soundtrack gen
invoker.setEnabled(true);
frame.dispose();
}
}
}
zip.setComment(container.toString());
zip.close();
} catch (Exception e) {
fileChooser.getSelectedFile().delete(); //cleanup
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(frame, "An error has occured.\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
return;
}
JOptionPane.showMessageDialog(frame, "Mod file created", "Success", JOptionPane.INFORMATION_MESSAGE);
Main.deleteDir(new File(Main.inpath + "temp/")); // soundtrack gen
invoker.setEnabled(true);
frame.dispose();
}
}
}
}

View File

@ -44,147 +44,145 @@ import org.json.JSONException;
import org.json.JSONObject;
public class Ernie implements ActionListener {
// Base URL for Gitea API
public static final String gitapi = "https://git.worlio.com/api/v1/repos/bonkmaykr/firestar";
public static final String changelog = "https://bonkmaykr.worlio.com/http/firestar/changelog.htm";
// Base URL for Gitea API
public static final String gitapi = "https://git.worlio.com/api/v1/repos/bonkmaykr/firestar";
public static final String changelog = "https://bonkmaykr.worlio.com/http/firestar/changelog.htm";
private HttpURLConnection httpConn;
private int contentLength;
private InputStream inputStream;
private HttpURLConnection httpConn;
private int contentLength;
private InputStream inputStream;
private JFrame frame = new JFrame();
private JPanel frameContainer;
private JEditorPane changelogDisplay;
private JButton notnowbtn;
private JButton surebtn;
private JFrame frame = new JFrame();
private JPanel frameContainer;
private JEditorPane changelogDisplay;
private JButton notnowbtn;
private JButton surebtn;
public boolean backgroundDone = false;
public boolean backgroundDone = false;
private JFrame parent;
private JFrame parent;
public Ernie(JFrame parent) {
this.parent = parent;
frame.setIconImage(Main.windowIcon);
byte[] urlraw = getFile(gitapi+"/releases?draft=false&pre-release=false");
if (urlraw.length <= 0) {
JOptionPane.showMessageDialog(frame, "Internal Error: Couldn't check for updates.", "Fatal Error", JOptionPane.ERROR_MESSAGE);
} else {
try {
JSONArray releases = new JSONArray(new String(urlraw, Charset.forName("utf-8")));
System.out.println("Updater: latest release is " + ((JSONObject)releases.get(0)).get("tag_name"));
if (releases.length() >= 1 && !((JSONObject)releases.get(0)).get("tag_name").equals(Main.vtag)) {
System.out.println("Updater: Your version is out of date.");
frame.add(frameContainer);
notnowbtn.addActionListener(this);
surebtn.addActionListener(this);
changelogDisplay.setEditable(false);
changelogDisplay.setPage(changelog);
changelogDisplay.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE); // makes text smaller than joe biden's windmill if font set manually. wtf??
public Ernie(JFrame parent) {
this.parent = parent;
frame.setIconImage(Main.windowIcon);
byte[] urlraw = getFile(gitapi+"/releases?draft=false&pre-release=false");
if (urlraw.length <= 0) {
JOptionPane.showMessageDialog(frame, "Internal Error: Couldn't check for updates.", "Fatal Error", JOptionPane.ERROR_MESSAGE);
} else {
try {
JSONArray releases = new JSONArray(new String(urlraw, Charset.forName("utf-8")));
System.out.println("Updater: latest release is " + ((JSONObject)releases.get(0)).get("tag_name"));
if (releases.length() >= 1 && !((JSONObject)releases.get(0)).get("tag_name").equals(Main.vtag)) {
System.out.println("Updater: Your version is out of date.");
frame.add(frameContainer);
notnowbtn.addActionListener(this);
surebtn.addActionListener(this);
changelogDisplay.setEditable(false);
changelogDisplay.setPage(changelog);
changelogDisplay.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE); // makes text smaller than joe biden's windmill if font set manually. wtf??
frame.setTitle("An update is available!");
frame.setSize(450, 400);
frame.setResizable(false);
frame.setLocationRelativeTo(parent);
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
parent.setEnabled(false);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
parent.setEnabled(true);
e.getWindow().dispose();
}
});
frame.setVisible(true);
} else { System.out.println("Updater: No updates."); }
} catch (IOException ex) {
Logger.getLogger(Ernie.class.getName()).log(Level.SEVERE, null, ex);
} catch (JSONException ex) {
Logger.getLogger(Ernie.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == notnowbtn) {
parent.setEnabled(true);
frame.dispose();
} else
if (actionEvent.getSource() == surebtn) {
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
String releasepage = "https://git.worlio.com/bonkmaykr/firestar/releases";
try {
Desktop.getDesktop().browse(new URI(releasepage));
parent.setEnabled(true);
frame.dispose();
} catch (Exception ex) {
JOptionPane.showMessageDialog(frame, "Couldn't open your web browser!\nYou can check out the latest release at the URL below:\n"+releasepage, "Error", JOptionPane.ERROR_MESSAGE);
frame.setTitle("An update is available!");
frame.setSize(450, 400);
frame.setResizable(false);
frame.setLocationRelativeTo(parent);
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
parent.setEnabled(false);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
parent.setEnabled(true);
e.getWindow().dispose();
}
});
frame.setVisible(true);
} else { System.out.println("Updater: No updates."); }
} catch (IOException | JSONException ex) {
Logger.getLogger(Ernie.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
byte[] getFile(String url) {
try {
URL fileURL = new URL(url);
httpConn = (HttpURLConnection) fileURL.openConnection();
int response = httpConn.getResponseCode();
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == notnowbtn) {
parent.setEnabled(true);
frame.dispose();
} else
if (actionEvent.getSource() == surebtn) {
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
String releasepage = "https://git.worlio.com/bonkmaykr/firestar/releases";
try {
Desktop.getDesktop().browse(new URI(releasepage));
parent.setEnabled(true);
frame.dispose();
} catch (Exception ex) {
JOptionPane.showMessageDialog(frame, "Couldn't open your web browser!\nYou can check out the latest release at the URL below:\n"+releasepage, "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
}
if (response == HttpURLConnection.HTTP_OK) {
contentLength = httpConn.getContentLength();
inputStream = httpConn.getInputStream();
} else if (response == 404) {
throw new IOException(
"File missing from remote server.");
} else {
throw new IOException(
"Unexpected response; Server replied with " + response);
}
ErnieDownloader ed = new ErnieDownloader(this, url, httpConn.getContentLength());
ed.doInBackground();
while (!backgroundDone) {}
byte[] getFile(String url) {
try {
URL fileURL = new URL(url);
httpConn = (HttpURLConnection) fileURL.openConnection();
int response = httpConn.getResponseCode();
inputStream.close();
httpConn.disconnect();
frame.dispose();
return ed.output;
} catch (MalformedURLException e) {
JOptionPane.showMessageDialog(frame, "Internal Error: URL given to Ernie is not valid.\nGet a programmer!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.dispose();
return new byte[]{};
} catch (Exception e) {
JOptionPane.showMessageDialog(frame, "Error: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.dispose();
return new byte[]{};
}
}
if (response == HttpURLConnection.HTTP_OK) {
contentLength = httpConn.getContentLength();
inputStream = httpConn.getInputStream();
} else if (response == 404) {
throw new IOException(
"File missing from remote server.");
} else {
throw new IOException(
"Unexpected response; Server replied with " + response);
}
ErnieDownloader ed = new ErnieDownloader(this, url, httpConn.getContentLength());
ed.doInBackground();
while (!backgroundDone) {}
inputStream.close();
httpConn.disconnect();
frame.dispose();
return ed.output;
} catch (MalformedURLException e) {
JOptionPane.showMessageDialog(frame, "Internal Error: URL given to Ernie is not valid.\nGet a programmer!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.dispose();
return new byte[]{};
} catch (Exception e) {
JOptionPane.showMessageDialog(frame, "Error: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.dispose();
return new byte[]{};
}
}
}
class ErnieDownloader extends SwingWorker<Void, Void> {
private static final int BUFFER_SIZE = 4096;
private String downloadURL;
private final Ernie gui;
public byte[] output;
private static final int BUFFER_SIZE = 4096;
private String downloadURL;
private final Ernie gui;
public byte[] output;
public ErnieDownloader(Ernie gui, String downloadURL, long size) {
this.gui = gui;
this.downloadURL = downloadURL;
}
@Override
protected Void doInBackground() throws Exception {
BufferedInputStream in = new BufferedInputStream(new URL(downloadURL).openStream());
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] data = new byte[16384];
int x;
while ((x = in.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, x);
public ErnieDownloader(Ernie gui, String downloadURL, long size) {
this.gui = gui;
this.downloadURL = downloadURL;
}
@Override
protected Void doInBackground() throws Exception {
BufferedInputStream in = new BufferedInputStream(new URL(downloadURL).openStream());
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] data = new byte[16384];
int x;
while ((x = in.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, x);
}
output = buffer.toByteArray();
in.close();
gui.backgroundDone = true;
return null;
}
output = buffer.toByteArray();
in.close();
gui.backgroundDone = true;
return null;
}
}

View File

@ -16,17 +16,16 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
public class FirescriptFormatException extends Exception {
public FirescriptFormatException() {
super();
}
public FirescriptFormatException() {
super();
}
public FirescriptFormatException(String msg) {
super(msg);
}
public FirescriptFormatException(String msg) {
super(msg);
}
public FirescriptFormatException(String cmd, String msg) {
super(cmd + ": " + msg);
}
public FirescriptFormatException(String cmd, String msg) {
super(cmd + ": " + msg);
}
}

View File

@ -24,151 +24,151 @@ import java.net.URL;
import java.net.*;
public class Fozzie {
private JFrame frame = new JFrame();
public JProgressBar progressBar;
private JPanel frameContainer;
private JLabel label;
private JFrame frame = new JFrame();
public JProgressBar progressBar;
private JPanel frameContainer;
private JLabel label;
private HttpURLConnection httpConn;
private int contentLength;
private InputStream inputStream;
private HttpURLConnection httpConn;
private int contentLength;
private InputStream inputStream;
public boolean backgroundDone = false;
public boolean backgroundDone = false;
boolean DownloadFile(String url, String odir, String oname) {
return DownloadFile(url, odir, oname, oname);
}
boolean DownloadFile(String url, String odir, String oname) {
return DownloadFile(url, odir, oname, oname);
}
boolean DownloadFile(String url, String odir, String oname, String dname) {
frame.add(frameContainer);
frame.setSize(300, 100);
frame.setTitle("Download in Progress");
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
frame.setIconImage(Main.windowIcon);
frame.setVisible(true);
boolean DownloadFile(String url, String odir, String oname, String dname) {
frame.add(frameContainer);
frame.setSize(300, 100);
frame.setTitle("Download in Progress");
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
frame.setIconImage(Main.windowIcon);
frame.setVisible(true);
label.setText("Downloading \"" + dname + "\"");
label.setText("Downloading \"" + dname + "\"");
try {
URL fileURL = new URL(url);
httpConn = (HttpURLConnection) fileURL.openConnection();
int response = httpConn.getResponseCode();
try {
URL fileURL = new URL(url);
httpConn = (HttpURLConnection) fileURL.openConnection();
int response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
String disposition = httpConn.getHeaderField("Content-Disposition");
String contentType = httpConn.getContentType();
contentLength = httpConn.getContentLength();
if (response == HttpURLConnection.HTTP_OK) {
String disposition = httpConn.getHeaderField("Content-Disposition");
String contentType = httpConn.getContentType();
contentLength = httpConn.getContentLength();
inputStream = httpConn.getInputStream();
} else if (response == 404) {
throw new IOException(
"File missing from remote server.");
} else {
throw new IOException(
"Unexpected response; Server replied with " + response);
}
new FozzieDownloader(this, url, odir, oname, httpConn.getContentLength()).doInBackground();
while (!backgroundDone) {}
inputStream = httpConn.getInputStream();
} else if (response == 404) {
throw new IOException(
"File missing from remote server.");
} else {
throw new IOException(
"Unexpected response; Server replied with " + response);
}
new FozzieDownloader(this, url, odir, oname, httpConn.getContentLength()).doInBackground();
while (!backgroundDone) {}
inputStream.close();
httpConn.disconnect();
frame.dispose();
return true;
} catch (MalformedURLException e) {
JOptionPane.showMessageDialog(frame, "Internal Error: URL given to Fozzie is not valid.\nGet a programmer!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.dispose();
return false;
} catch (Exception e) {
JOptionPane.showMessageDialog(frame, "Error: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.dispose();
return false;
}
}
inputStream.close();
httpConn.disconnect();
frame.dispose();
return true;
} catch (MalformedURLException e) {
JOptionPane.showMessageDialog(frame, "Internal Error: URL given to Fozzie is not valid.\nGet a programmer!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.dispose();
return false;
} catch (Exception e) {
JOptionPane.showMessageDialog(frame, "Error: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.dispose();
return false;
}
}
public void displayTextOnly(String text, String title) {
frame.add(frameContainer);
frame.setSize(300, 100);
frame.setTitle(title);
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
frame.setIconImage(Main.windowIcon);
frame.setVisible(true);
public void displayTextOnly(String text, String title) {
frame.add(frameContainer);
frame.setSize(300, 100);
frame.setTitle(title);
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
frame.setIconImage(Main.windowIcon);
frame.setVisible(true);
label.setText(text);
label.setText(text);
progressBar.setVisible(false);
}
progressBar.setVisible(false);
}
public void setText(String text, String title) {
label.setText(text);
frame.setTitle(title);
}
public void setText(String text, String title) {
label.setText(text);
frame.setTitle(title);
}
public void destroyDialog() {
frame.setVisible(false);
frame.dispose();
}
public void destroyDialog() {
frame.setVisible(false);
frame.dispose();
}
public void disconnect() throws IOException {
inputStream.close();
httpConn.disconnect();
}
public void disconnect() throws IOException {
inputStream.close();
httpConn.disconnect();
}
public int getContentLength() {
return this.contentLength;
}
public int getContentLength() {
return this.contentLength;
}
public InputStream getInputStream() {
return this.inputStream;
}
public InputStream getInputStream() {
return this.inputStream;
}
}
class FozzieDownloader extends SwingWorker<Void, Void> {
private static final int BUFFER_SIZE = 4096;
private String downloadURL;
private String saveDirectory;
private String saveName;
private final Fozzie gui;
private final long completeSize;
private static final int BUFFER_SIZE = 4096;
private String downloadURL;
private String saveDirectory;
private String saveName;
private final Fozzie gui;
private final long completeSize;
public FozzieDownloader(Fozzie gui, String downloadURL, String saveDirectory, String saveName, long size) {
this.gui = gui;
this.downloadURL = downloadURL;
this.saveDirectory = saveDirectory;
this.saveName = saveName;
this.completeSize = size;
}
public FozzieDownloader(Fozzie gui, String downloadURL, String saveDirectory, String saveName, long size) {
this.gui = gui;
this.downloadURL = downloadURL;
this.saveDirectory = saveDirectory;
this.saveName = saveName;
this.completeSize = size;
}
@Override
protected Void doInBackground() throws Exception {
long downloadedSize = 0;
File downloadLocationDir = new File(saveDirectory);
File downloadLocation = new File(saveDirectory + "/" + saveName);
downloadLocationDir.mkdirs();
if (!downloadLocation.isFile()) {
downloadLocation.createNewFile();
}
BufferedInputStream in = new BufferedInputStream(new URL(downloadURL).openStream());
FileOutputStream fos = new FileOutputStream(saveDirectory + "/" + saveName);
BufferedOutputStream out = new BufferedOutputStream(fos,1024);
byte[] data = new byte[1024];
int x = 0;
while ((x = in.read(data,0,1024))>=0) {
downloadedSize += x;
int progress = (int) ((((double)downloadedSize) / ((double)completeSize)) * 100d);
gui.progressBar.setValue(progress);
out.write(data, 0, x);
}
out.close();
in.close();
gui.backgroundDone = true;
return null;
}
@Override
protected Void doInBackground() throws Exception {
long downloadedSize = 0;
File downloadLocationDir = new File(saveDirectory);
File downloadLocation = new File(saveDirectory + "/" + saveName);
downloadLocationDir.mkdirs();
if (!downloadLocation.isFile()) {
downloadLocation.createNewFile();
}
BufferedInputStream in = new BufferedInputStream(new URL(downloadURL).openStream());
FileOutputStream fos = new FileOutputStream(saveDirectory + "/" + saveName);
BufferedOutputStream out = new BufferedOutputStream(fos,1024);
byte[] data = new byte[1024];
int x = 0;
while ((x = in.read(data,0,1024))>=0) {
downloadedSize += x;
int progress = (int) ((((double)downloadedSize) / ((double)completeSize)) * 100d);
gui.progressBar.setValue(progress);
out.write(data, 0, x);
}
out.close();
in.close();
gui.backgroundDone = true;
return null;
}
}

View File

@ -16,9 +16,6 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import com.github.difflib.DiffUtils;
import com.github.difflib.UnifiedDiffUtils;
import com.github.difflib.patch.Patch;
import net.lingala.zip4j.ZipFile;
import javax.swing.*;
@ -35,337 +32,331 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
public class Gonzo {
JFrame frame = new JFrame();
private JPanel frameContainer;
private JTextArea consoleDisplay;
private JScrollPane scrollPane;
public boolean data0;
public boolean data1;
public boolean data2;
public boolean dlc1;
public boolean dlc2;
private MissPiggy invoker;
public String oArcTarget = "dlc2.psarc"; // which psarc to rebuild the assets in
JFrame frame = new JFrame();
private JPanel frameContainer;
private JTextArea consoleDisplay;
private JScrollPane scrollPane;
public boolean data0;
public boolean data1;
public boolean data2;
public boolean dlc1;
public boolean dlc2;
private MissPiggy invoker;
public String oArcTarget = "dlc2.psarc"; // which psarc to rebuild the assets in
// TODO 1.3: Implement requires boolean[] from Main.Mod
// Rework system to choose the last PSARC and then add more before it when called by requires[]
// Instead of the current system where it simply grabs them all and bloats the file.
//
// EDIT: requires[] is now an arraylist of booleans[], each a supported minimum combination of PSARCs.
// if any one of them is met, gonzo may continue
// for example:
// [false, true, false, false], [true, false, false, false] // user only needs either base psarc or patches PSARC, one or the other (having both is OK)
// [true, true, false, false] // user needs both base and patches
// [false, false, true, true] // user needs the HD DLC and the Fury DLC
//
// if none is found, assume "new boolean[]{false, false, false, false}" (no PSARCs required)
// (at least one of any 4 psarcs will already be checked for by MissPiggy so this is an okay way to implement it.)
// TODO 1.3: Implement requires boolean[] from Main.Mod
// Rework system to choose the last PSARC and then add more before it when called by requires[]
// Instead of the current system where it simply grabs them all and bloats the file.
//
// EDIT: requires[] is now an arraylist of booleans[], each a supported minimum combination of PSARCs.
// if any one of them is met, gonzo may continue
// for example:
// [false, true, false, false], [true, false, false, false] // user only needs either base psarc or patches PSARC, one or the other (having both is OK)
// [true, true, false, false] // user needs both base and patches
// [false, false, true, true] // user needs the HD DLC and the Fury DLC
//
// if none is found, assume "new boolean[]{false, false, false, false}" (no PSARCs required)
// (at least one of any 4 psarcs will already be checked for by MissPiggy so this is an okay way to implement it.)
public void DeployMods(MissPiggy inv) {
invoker = inv;
System.out.println("\n\nStarting mod deployment\n\n");
public void DeployMods(MissPiggy inv) {
invoker = inv;
System.out.println("\n\nStarting mod deployment\n\n");
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
frame.setIconImage(Main.windowIcon);
frame.setSize(800, 400);
frame.setMinimumSize(new Dimension(600,400));
frame.setTitle("Mod Installation");
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(inv.frame);
frame.setAlwaysOnTop(true);
frame.setVisible(true);
frame.setIconImage(Main.windowIcon);
frame.setSize(800, 400);
frame.setMinimumSize(new Dimension(600,400));
frame.setTitle("Mod Installation");
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(inv.frame);
frame.setAlwaysOnTop(true);
frame.setVisible(true);
File psarcHandle = new File(Main.inpath + "data.psarc");
data0 = psarcHandle.isFile();
psarcHandle = new File(Main.inpath + "data1.psarc");
data1 = psarcHandle.isFile();
psarcHandle = new File(Main.inpath + "data2.psarc");
data2 = psarcHandle.isFile();
psarcHandle = new File(Main.inpath + "dlc1.psarc");
dlc1 = psarcHandle.isFile();
psarcHandle = new File(Main.inpath + "dlc2.psarc");
dlc2 = psarcHandle.isFile();
File psarcHandle = new File(Main.inpath + "data.psarc");
data0 = psarcHandle.isFile();
psarcHandle = new File(Main.inpath + "data1.psarc");
data1 = psarcHandle.isFile();
psarcHandle = new File(Main.inpath + "data2.psarc");
data2 = psarcHandle.isFile();
psarcHandle = new File(Main.inpath + "dlc1.psarc");
dlc1 = psarcHandle.isFile();
psarcHandle = new File(Main.inpath + "dlc2.psarc");
dlc2 = psarcHandle.isFile();
System.out.println("Source files discovered: data " + data0 + ", data1 " + data1 + ", data2 " + data2 + ", dlc1 " + dlc1 + ", dlc2 " + dlc2);
System.out.println("Source files discovered: data " + data0 + ", data1 " + data1 + ", data2 " + data2 + ", dlc1 " + dlc1 + ", dlc2 " + dlc2);
final Thread managerThread = new Thread() {
@Override
public void run() {
if (/*Main.repatch*/true) { //todo implement fast mode correctly or remove
CompatibilityRoutine();
} else {
FastRoutine();
}
}
};
managerThread.start();
}
private void CompatibilityRoutine() {
// create temporary working area for asset dump
new File(System.getProperty("user.home") + "/.firestar/temp/").mkdirs();
// decide which files to dump
List<String> dumpThese = new ArrayList<String>();
if (data0) {dumpThese.add("data.psarc");oArcTarget = "data.psarc";}
if (data1) {dumpThese.add("data1.psarc");oArcTarget = "data1.psarc";}
if (data2) {dumpThese.add("data2.psarc");oArcTarget = "data2.psarc";}
if (dlc1) {dumpThese.add("dlc1.psarc");oArcTarget = "dlc1.psarc";}
if (dlc2) {dumpThese.add("dlc2.psarc");oArcTarget = "dlc2.psarc";}
// dump all assets to working area
for (String s : dumpThese) {
try {
System.out.println("Firestar is extracting " + s);
consoleDisplay.append("Firestar is extracting " + s + "\n");
//Process p = Runtime.getRuntime().exec(new String[]{"bash","-c","aplay /home/bonkyboo/kittens_loop.wav"}); // DEBUG
Process p = Main.exec(new String[]{"../psp2psarc.exe", "extract", "-y", "../"+s}, System.getProperty("user.home") + "/.firestar/temp/");
final Thread ioThread = new Thread() {
@Override
public void run() {
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
consoleDisplay.append(line + "\n");
try {scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());}
catch (Exception e) {System.out.println("WARNING: Swing failed to paint window due to race condition. You can safely ignore this.\n" + e.getMessage());}
}
reader.close();
} catch (final Exception e) {
e.printStackTrace(); // will probably definitely absolutely for sure hang firestar unless we do something. Too bad!
}
}
};
ioThread.start();
p.waitFor();
} catch (IOException | InterruptedException e) {
System.out.println(e.getMessage());
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
return;
}
}
// overwrite assets with custom ones from each mod and/or perform operations as specified in mod's delete list
// todo: implement RegEx functions after delete.txt
for (Main.Mod m : Main.Mods) {
if (m.enabled) {
try {
System.out.println("Firestar is extracting " + m.friendlyName + " by " + m.author);
consoleDisplay.append("Firestar is extracting " + m.friendlyName + " by " + m.author + "\n");
new ZipFile(System.getProperty("user.home") + "/.firestar/mods/" + m.path).extractAll(System.getProperty("user.home") + "/.firestar/temp/");
File fscript = new File(Main.inpath + "temp/fscript");
if (fscript.exists()) {
new Rizzo(new FileInputStream(fscript), Main.inpath + "temp/"); // Lets rizz this mod up
fscript.delete();
}
if (new File(System.getProperty("user.home") + "/.firestar/temp/delete.txt").isFile()) {
System.out.println("Firestar is deleting files that conflict with " + m.friendlyName + " by " + m.author);
consoleDisplay.append("Firestar is deleting files that conflict with " + m.friendlyName + " by " + m.author + "\n");
String deleteQueue = new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "/.firestar/temp/delete.txt")));
if (Main.windows) {deleteQueue = new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "\\.firestar\\temp\\delete.txt")));} // might be unnecessary
String[] dQarray = deleteQueue.split("\n");
Arrays.sort(dQarray);
System.out.println("The deletion queue is " + dQarray.length + " files long!"); //debug
for (String file : dQarray) {
if(file.contains("..")) { //todo: is this safe enough?
System.out.println("WARNING: Firestar skipped a potentially dangerous delete command. Please ensure the mod you're installing is from someone you trust!");
consoleDisplay.append("WARNING: Firestar skipped a potentially dangerous delete command. Please ensure the mod you're installing is from someone you trust!\n");
} else {
if (!Main.windows) {
System.out.println("Deleting " + System.getProperty("user.home") + "/.firestar/temp/data/" + file);
consoleDisplay.append("Deleting " + System.getProperty("user.home") + "/.firestar/temp/data/" + file + "\n");
new File(System.getProperty("user.home") + "/.firestar/temp/data" + file).delete();}
else {
System.out.println("Deleting " + new String(System.getProperty("user.home") + "\\.firestar\\temp\\data" + file).replace("/", "\\"));
consoleDisplay.append("Deleting " + new String(System.getProperty("user.home") + "\\.firestar\\temp\\data" + file).replace("/", "\\") + "\n");
new File(new String(System.getProperty("user.home") + "\\.firestar\\temp\\data" + file).replace("/", "\\")).delete();
}
}
}
// cleanup so we don't run it again for the next mod unless needed
// this is not necessary but good practice
new File(System.getProperty("user.home") + "/.firestar/temp/delete.txt").delete();
}
} catch (Exception e) {
System.out.println(e.getMessage());
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
return;
}
}
}
// Post fscript changes
try (InputStream is = Main.class.getResourceAsStream("/post.fscript")) {
new Rizzo(is, Main.inpath + "temp/");
} catch (IOException | FirescriptFormatException e) {
System.out.println(e.getMessage());
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
return;
final Thread managerThread = new Thread() {
@Override
public void run() {
if (/*Main.repatch*/true) { //todo implement fast mode correctly or remove
CompatibilityRoutine();
} else {
FastRoutine();
}
}
};
managerThread.start();
}
// create a list of the contents of data/ for psp2psarc.exe to read from
List<String> oFilesList = new ArrayList<String>();
List<String> oFilesList2 = new ArrayList<String>();
try {
listAllFiles(Paths.get(System.getProperty("user.home") + "/.firestar/temp/data/"), oFilesList);
for (String p : oFilesList) {
// We need to clean up the path here on Linux to avoid psp2psarc getting confused about where the hell "/" is.
// In WINE it should see it as Z: by default, but if it's somewhere else then I don't have an elegant way of knowing what drive letter it's on, so
// relative paths are kind of the only choice here. This can be extended to Windows too as it works there, though completely unnecessary.
if (!Main.windows) {oFilesList2.add(p.replace("\\", "/").split(new String(System.getProperty("user.home") + "/.firestar/temp/"))[1]);}
else {oFilesList2.add(p.split(new String(System.getProperty("user.home") + "\\.firestar\\temp\\").replace("\\", "\\\\"))[1]);} // path wont match regex unless adjusted for windows here
}
//oFilesList2.forEach(System.out::println); //debug
File oFilesListO = new File(System.getProperty("user.home") + "/.firestar/temp/list.txt");
if (oFilesListO.isFile()) {oFilesListO.delete();}
FileWriter oFilesListWr = new FileWriter(oFilesListO, true);
int i = 0;
for (String p : oFilesList2) {
oFilesListWr.append(p);
if (i != oFilesList2.size()) {
oFilesListWr.append("\n");
}
i++;
}
oFilesListWr.close();
} catch (Exception e) {
System.out.println(e.getMessage());
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
return;
}
private void CompatibilityRoutine() {
// create temporary working area for asset dump
new File(System.getProperty("user.home") + "/.firestar/temp/").mkdirs();
// invoke psp2psarc.exe one final time to reconstruct the assets
try {
System.out.println("Firestar is compiling the final build");
consoleDisplay.append("Firestar is compiling the final build" + "\n");
Process p = Main.exec(new String[]{"../psp2psarc.exe", "create", "--skip-missing-files", "-j12", "-a", "-i", "-y", "--input-file=list.txt", "-o" + oArcTarget}, System.getProperty("user.home") + "/.firestar/temp/");
final Thread ioThread = new Thread() {
@Override
public void run() {
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
consoleDisplay.append(line + "\n");
try {scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());}
catch (Exception e) {System.out.println("WARNING: Swing failed to paint window due to race condition.\n" + e.getMessage());}
}
reader.close();
} catch (final Exception e) {
e.printStackTrace(); // will probably definitely absolutely for sure hang firestar unless we do something. Too bad!
}
}
};
ioThread.start();
p.waitFor();
} catch (IOException | InterruptedException e) {
System.out.println(e.getMessage());
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
return;
}
// decide which files to dump
List<String> dumpThese = new ArrayList<String>();
if (data0) {dumpThese.add("data.psarc");oArcTarget = "data.psarc";}
if (data1) {dumpThese.add("data1.psarc");oArcTarget = "data1.psarc";}
if (data2) {dumpThese.add("data2.psarc");oArcTarget = "data2.psarc";}
if (dlc1) {dumpThese.add("dlc1.psarc");oArcTarget = "dlc1.psarc";}
if (dlc2) {dumpThese.add("dlc2.psarc");oArcTarget = "dlc2.psarc";}
// cleanup
boolean one = new File(Main.outpath).mkdirs();
boolean two;
System.out.println("created export folder: " + one);
if (new File(Main.outpath + oArcTarget).exists()) {System.out.println("deleting existing file: " + Main.outpath + oArcTarget); new File(Main.outpath + oArcTarget).delete();} //hackjob
if (!Main.windows) {two = new File(System.getProperty("user.home") + "/.firestar/temp/" + oArcTarget).renameTo(new File(Main.outpath + oArcTarget));}
else {two = new File(System.getProperty("user.home") + "\\.firestar\\temp\\" + oArcTarget).renameTo(new File(Main.outpath + oArcTarget));}
System.out.println("moved file to destination: " + two);
if (two) {System.out.println("file should be located at " + Main.outpath + oArcTarget);} else {
System.out.println("CRITICAL FAILURE: Please check that your output path is correct and that you have write permissions!");
consoleDisplay.append("CRITICAL FAILURE: Please check that your output path is correct and that you have write permissions!");
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: Please check that your output path is correct and that you have write permissions!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
return;
}
try {
File tmp = new File(System.getProperty("user.home") + "/.firestar/temp/");
Main.deleteDir(tmp);
} catch (Exception e) {
System.out.println("WARNING: Temporary files may not have been properly cleared.\n" + e.getMessage());
consoleDisplay.append("WARNING: Temporary files may not have been properly cleared.\n" + e.getMessage());
}
// dump all assets to working area
for (String s : dumpThese) {
try {
System.out.println("Firestar is extracting " + s);
consoleDisplay.append("Firestar is extracting " + s + "\n");
//Process p = Runtime.getRuntime().exec(new String[]{"bash","-c","aplay /home/bonkyboo/kittens_loop.wav"}); // DEBUG
Process p = Main.exec(new String[]{"../psp2psarc.exe", "extract", "-y", "../"+s}, System.getProperty("user.home") + "/.firestar/temp/");
final Thread ioThread = new Thread() {
@Override
public void run() {
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
consoleDisplay.append(line + "\n");
try {scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());}
catch (Exception e) {System.out.println("WARNING: Swing failed to paint window due to race condition. You can safely ignore this.\n" + e.getMessage());}
}
reader.close();
} catch (final Exception e) {
e.printStackTrace(); // will probably definitely absolutely for sure hang firestar unless we do something. Too bad!
}
}
};
ioThread.start();
p.waitFor();
} catch (IOException | InterruptedException e) {
System.out.println(e.getMessage());
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
return;
}
}
// done!
try {
TimeUnit.SECONDS.sleep(1); // avoid race condition when logging
} catch (InterruptedException e) {
//ignore
}
// overwrite assets with custom ones from each mod and/or perform operations as specified in mod's delete list
// todo: implement RegEx functions after delete.txt
for (Main.Mod m : Main.Mods) {
if (m.enabled) {
try {
System.out.println("Firestar is extracting " + m.friendlyName + " by " + m.author);
consoleDisplay.append("Firestar is extracting " + m.friendlyName + " by " + m.author + "\n");
new ZipFile(System.getProperty("user.home") + "/.firestar/mods/" + m.path).extractAll(System.getProperty("user.home") + "/.firestar/temp/");
((TitledBorder)scrollPane.getBorder()).setTitle("DONE! Close this pop-up to continue.");
scrollPane.repaint();
File fscript = new File(Main.inpath + "temp/fscript");
if (fscript.exists()) {
new Rizzo(new FileInputStream(fscript), Main.inpath + "temp/"); // Lets rizz this mod up
fscript.delete();
}
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
}
if (new File(System.getProperty("user.home") + "/.firestar/temp/delete.txt").isFile()) {
System.out.println("Firestar is deleting files that conflict with " + m.friendlyName + " by " + m.author);
consoleDisplay.append("Firestar is deleting files that conflict with " + m.friendlyName + " by " + m.author + "\n");
private void FastRoutine() {
String deleteQueue = new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "/.firestar/temp/delete.txt")));
if (Main.windows) {deleteQueue = new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "\\.firestar\\temp\\delete.txt")));} // might be unnecessary
String[] dQarray = deleteQueue.split("\n");
Arrays.sort(dQarray);
System.out.println("The deletion queue is " + dQarray.length + " files long!"); //debug
}
for (String file : dQarray) {
if(file.contains("..")) { //todo: is this safe enough?
System.out.println("WARNING: Firestar skipped a potentially dangerous delete command. Please ensure the mod you're installing is from someone you trust!");
consoleDisplay.append("WARNING: Firestar skipped a potentially dangerous delete command. Please ensure the mod you're installing is from someone you trust!\n");
} else {
if (!Main.windows) {
System.out.println("Deleting " + System.getProperty("user.home") + "/.firestar/temp/data/" + file);
consoleDisplay.append("Deleting " + System.getProperty("user.home") + "/.firestar/temp/data/" + file + "\n");
new File(System.getProperty("user.home") + "/.firestar/temp/data" + file).delete();}
else {
System.out.println("Deleting " + new String(System.getProperty("user.home") + "\\.firestar\\temp\\data" + file).replace("/", "\\"));
consoleDisplay.append("Deleting " + new String(System.getProperty("user.home") + "\\.firestar\\temp\\data" + file).replace("/", "\\") + "\n");
new File(new String(System.getProperty("user.home") + "\\.firestar\\temp\\data" + file).replace("/", "\\")).delete();
}
}
}
public void AllowExit() {
System.out.println("\n\nYou may now close the pop-up window.");
consoleDisplay.append("\n\n\nYou may now close the pop-up window.");
try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {} //ignore
scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
invoker.wrapUpDeployment();
e.getWindow().dispose();
}
});
}
// cleanup so we don't run it again for the next mod unless needed
// this is not necessary but good practice
new File(System.getProperty("user.home") + "/.firestar/temp/delete.txt").delete();
}
} catch (Exception e) {
System.out.println(e.getMessage());
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
return;
}
}
}
private static void listAllFiles(Path currentPath, List<String> allFiles)
throws IOException
{
try (DirectoryStream<Path> stream = Files.newDirectoryStream(currentPath))
{
for (Path entry : stream) {
if (Files.isDirectory(entry)) {
listAllFiles(entry, allFiles);
} else {
allFiles.add(entry.toString());
}
}
}
}
// Post fscript changes
try (InputStream is = Main.class.getResourceAsStream("/post.fscript")) {
new Rizzo(is, Main.inpath + "temp/");
} catch (IOException | FirescriptFormatException e) {
System.out.println(e.getMessage());
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
return;
}
// create a list of the contents of data/ for psp2psarc.exe to read from
List<String> oFilesList = new ArrayList<String>();
List<String> oFilesList2 = new ArrayList<String>();
try {
listAllFiles(Paths.get(System.getProperty("user.home") + "/.firestar/temp/data/"), oFilesList);
for (String p : oFilesList) {
// We need to clean up the path here on Linux to avoid psp2psarc getting confused about where the hell "/" is.
// In WINE it should see it as Z: by default, but if it's somewhere else then I don't have an elegant way of knowing what drive letter it's on, so
// relative paths are kind of the only choice here. This can be extended to Windows too as it works there, though completely unnecessary.
if (!Main.windows) {oFilesList2.add(p.replace("\\", "/").split(new String(System.getProperty("user.home") + "/.firestar/temp/"))[1]);}
else {oFilesList2.add(p.split(new String(System.getProperty("user.home") + "\\.firestar\\temp\\").replace("\\", "\\\\"))[1]);} // path wont match regex unless adjusted for windows here
}
//oFilesList2.forEach(System.out::println); //debug
File oFilesListO = new File(System.getProperty("user.home") + "/.firestar/temp/list.txt");
if (oFilesListO.isFile()) {oFilesListO.delete();}
FileWriter oFilesListWr = new FileWriter(oFilesListO, true);
int i = 0;
for (String p : oFilesList2) {
oFilesListWr.append(p);
if (i != oFilesList2.size()) {
oFilesListWr.append("\n");
}
i++;
}
oFilesListWr.close();
} catch (Exception e) {
System.out.println(e.getMessage());
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
return;
}
// invoke psp2psarc.exe one final time to reconstruct the assets
try {
System.out.println("Firestar is compiling the final build");
consoleDisplay.append("Firestar is compiling the final build" + "\n");
Process p = Main.exec(new String[]{"../psp2psarc.exe", "create", "--skip-missing-files", "-j12", "-a", "-i", "-y", "--input-file=list.txt", "-o" + oArcTarget}, System.getProperty("user.home") + "/.firestar/temp/");
final Thread ioThread = new Thread() {
@Override
public void run() {
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
consoleDisplay.append(line + "\n");
try {scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());}
catch (Exception e) {System.out.println("WARNING: Swing failed to paint window due to race condition.\n" + e.getMessage());}
}
reader.close();
} catch (final Exception e) {
e.printStackTrace(); // will probably definitely absolutely for sure hang firestar unless we do something. Too bad!
}
}
};
ioThread.start();
p.waitFor();
} catch (IOException | InterruptedException e) {
System.out.println(e.getMessage());
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
return;
}
// cleanup
boolean one = new File(Main.outpath).mkdirs();
boolean two;
System.out.println("created export folder: " + one);
if (new File(Main.outpath + oArcTarget).exists()) {System.out.println("deleting existing file: " + Main.outpath + oArcTarget); new File(Main.outpath + oArcTarget).delete();} //hackjob
if (!Main.windows) {two = new File(System.getProperty("user.home") + "/.firestar/temp/" + oArcTarget).renameTo(new File(Main.outpath + oArcTarget));}
else {two = new File(System.getProperty("user.home") + "\\.firestar\\temp\\" + oArcTarget).renameTo(new File(Main.outpath + oArcTarget));}
System.out.println("moved file to destination: " + two);
if (two) {System.out.println("file should be located at " + Main.outpath + oArcTarget);} else {
System.out.println("CRITICAL FAILURE: Please check that your output path is correct and that you have write permissions!");
consoleDisplay.append("CRITICAL FAILURE: Please check that your output path is correct and that you have write permissions!");
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: Please check that your output path is correct and that you have write permissions!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
return;
}
try {
File tmp = new File(System.getProperty("user.home") + "/.firestar/temp/");
Main.deleteDir(tmp);
} catch (Exception e) {
System.out.println("WARNING: Temporary files may not have been properly cleared.\n" + e.getMessage());
consoleDisplay.append("WARNING: Temporary files may not have been properly cleared.\n" + e.getMessage());
}
// done!
try {
TimeUnit.SECONDS.sleep(1); // avoid race condition when logging
} catch (InterruptedException e) {
//ignore
}
((TitledBorder)scrollPane.getBorder()).setTitle("DONE! Close this pop-up to continue.");
scrollPane.repaint();
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
}
private void FastRoutine() {
}
public void AllowExit() {
System.out.println("\n\nYou may now close the pop-up window.");
consoleDisplay.append("\n\n\nYou may now close the pop-up window.");
try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {} //ignore
scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
invoker.wrapUpDeployment();
e.getWindow().dispose();
}
});
}
private static void listAllFiles(Path currentPath, List<String> allFiles) throws IOException {
try (DirectoryStream<Path> stream = Files.newDirectoryStream(currentPath)) {
for (Path entry : stream) {
if (Files.isDirectory(entry)) {
listAllFiles(entry, allFiles);
} else {
allFiles.add(entry.toString());
}
}
}
}
}

View File

@ -30,224 +30,224 @@ import javax.imageio.ImageIO;
import javax.swing.*;
public class Main {
// Build Information
public static final String vstr = "Release 1.3";
public static final String vcode = "Tetsuo";
public static final String vtag = "tetsuo-1.3"; // set to dekka-1.1 for testing
public static final int vint = 1;
// Build Information
public static final String vstr = "Release 1.3";
public static final String vcode = "Tetsuo";
public static final String vtag = "tetsuo-1.3"; // set to dekka-1.1 for testing
public static final int vint = 1;
// User Settings
public static String outpath = System.getProperty("user.home") + "/.firestar/out/"; //game assets location
public final static String inpath = System.getProperty("user.home") + "/.firestar/"; //firestar folder -- do not change this
public static boolean repatch; //are we in compat mode?
public static boolean windows; //True = windows
public static int confvint = vint;
public static boolean checkUpdates = true;
//public static String psarc; //sdk location
// User Settings
public static String outpath = System.getProperty("user.home") + "/.firestar/out/"; //game assets location
public final static String inpath = System.getProperty("user.home") + "/.firestar/"; //firestar folder -- do not change this
public static boolean repatch; //are we in compat mode?
public static boolean windows; //True = windows
public static int confvint = vint;
public static boolean checkUpdates = true;
//public static String psarc; //sdk location
public enum ArcTarget { // install target for 2048, type used by downloader
BASE("http://zeus.dl.playstation.net/cdn/UP9000/PCSA00015_00/NYEoaBGfiWymSEVZKxoyrKyBFsZNoFqxdyAIpZayZYuLLbCAArYrYXjPNhKCfXcONmhIZzZEeArycSrjiJOuNMWuWsDONUxMIQtMk.pkg"),
LATEST("http://gs.ww.np.dl.playstation.net/ppkg/np/PCSA00015/PCSA00015_T5/a4b7d9e35ed56e86/UP9000-PCSA00015_00-WIPEOUT2048BASE0-A0104-V0100-059564fcab8ce66d19b5a563e92677e581313205-PE.pkg"),
ADDON_HD("http://zeus.dl.playstation.net/cdn/UP9000/PCSA00015_00/JYMqGNXUKqHEyNLjbOgrWcJdnQJUMzgadRFWekbWFBXAwMeGikOyiHkXKogKIfqGhtNwKgmNWwwcrJORmRUTDzylBPwjGVnVjyDfh.pkg"),
ADDON_HD_FURY("http://zeus.dl.playstation.net/cdn/UP9000/PCSA00015_00/IAoJQaDpySenBmQCKiqecEPMzSdPfPcdXupxZXLTYYTuRgtsdTaHxbeejwGKRQpjJOKBdMMFzSoeEhsHYxNUasQrEzkZPeBxUEqnp.pkg");
public enum ArcTarget { // install target for 2048, type used by downloader
BASE("http://zeus.dl.playstation.net/cdn/UP9000/PCSA00015_00/NYEoaBGfiWymSEVZKxoyrKyBFsZNoFqxdyAIpZayZYuLLbCAArYrYXjPNhKCfXcONmhIZzZEeArycSrjiJOuNMWuWsDONUxMIQtMk.pkg"),
LATEST("http://gs.ww.np.dl.playstation.net/ppkg/np/PCSA00015/PCSA00015_T5/a4b7d9e35ed56e86/UP9000-PCSA00015_00-WIPEOUT2048BASE0-A0104-V0100-059564fcab8ce66d19b5a563e92677e581313205-PE.pkg"),
ADDON_HD("http://zeus.dl.playstation.net/cdn/UP9000/PCSA00015_00/JYMqGNXUKqHEyNLjbOgrWcJdnQJUMzgadRFWekbWFBXAwMeGikOyiHkXKogKIfqGhtNwKgmNWwwcrJORmRUTDzylBPwjGVnVjyDfh.pkg"),
ADDON_HD_FURY("http://zeus.dl.playstation.net/cdn/UP9000/PCSA00015_00/IAoJQaDpySenBmQCKiqecEPMzSdPfPcdXupxZXLTYYTuRgtsdTaHxbeejwGKRQpjJOKBdMMFzSoeEhsHYxNUasQrEzkZPeBxUEqnp.pkg");
private final String value;
ArcTarget(final String value) {this.value = value;}
private final String value;
ArcTarget(final String value) {this.value = value;}
@Override
public String toString() {
return value;
}
}
public enum ArcKey { // decryption keys for 2048, type used by downloader
BASE("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
LATEST("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
ADDON_HD("KO5ifR1dQ+eHBlgi6TI0Bdnv4uNsGG5kYGIR4Ojs7ejuis9/anXfuudVNvzgdu+9z1z+asJojA9uAACgRhTl"),
ADDON_HD_FURY("KO5ifR1dQ+eHBlgi6TI0Bdnv4uNsFG5kYGIR4Ojs7ejuis9/3fydBRm3eCJX7biz/vVTm/2jMT64AQCCYhVy");
private final String value;
ArcKey(final String value) {this.value = value;}
@Override
public String toString() {
return value;
}
}
public class Mod {
public String path; // file name
public int version = 1;
public int priority = 0; //unused
public String friendlyName;
public String description = "";
public String game; //TODO for multi game support
public int loaderversion = 0; //minimum required vint or feature level from Firestar
public String author; // if null, "Author is unknown."
public boolean enabled = true;
public List<boolean[]> requires = new ArrayList<>(); // TODO: load optional "requires" array from mod meta if it exists. it will be base, patches, hd dlc, and fury dlc in that order.
// TODO: save 'false true false false' in ost gen if necessary (patches change localization)
}
// Mods
public static List<Mod> Mods = new ArrayList<Mod>();
// UI Global Assets
public static Font fExo2;
public static BufferedImage windowIcon;
public static void main(String[] args) {
// license string
System.out.printf("FIRESTAR MOD MANAGER for WipEout 2048\nversion " + vstr + " (codename " + vcode + ") major " + vint + "\n" +
"JVM host appears to be " + System.getProperty("os.name") +
"\nRunning from " + System.getProperty("user.dir") +
"\nCopyright (C) 2024 bonkmaykr\n\nThis program is free software: you can redistribute it and/or modify\n" +
"it under the terms of the GNU General Public License as published by\n" +
"the Free Software Foundation, either version 3 of the License, or\n" +
"(at your option) any later version.\n" +
"\n" +
"This program is distributed in the hope that it will be useful,\n" +
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +
"GNU General Public License for more details.\n" +
"\n" +
"You should have received a copy of the GNU General Public License\n" +
"along with this program. If not, see https://www.gnu.org/licenses/.\n\n\n\n");
//begin
// load global assets
try {
fExo2 = Font.createFont(Font.TRUETYPE_FONT, Main.class.getResourceAsStream("/exo2.ttf"));
} catch (Exception e) {
System.out.println("Font \"Exo 2\" is missing!");
fExo2 = new Font("Arial", Font.PLAIN, 12);
}
// load global window icon
try {
windowIcon = ImageIO.read(Main.class.getResourceAsStream("/titleIcon.png"));
} catch (IOException e) {
System.out.println("ERROR: Failed to find titleIcon.png. Window will not have an icon.");
}
// check and load configs
File fConf = new File(System.getProperty("user.home") + "/.firestar/firestar.conf");
if (!fConf.isFile()) {
System.out.println("No configuration was found. Starting the initial setup");
new WilkinsCoffee().setup();
} else {
new MissPiggy().Action(); // Quick! Start singing Firework by Katy Perry! (or open the main window i guess...)
}
}
public static void writeConf(){
JSONObject container = new JSONObject();
container.put("version", vint);
container.put("2048path", outpath);
container.put("HDpath", "TODO"); // proposed hd/fury support for ps3, will use very simplified Fast Mode due to less difficulty installing
container.put("safemode", repatch);
container.put("isWin32", windows);
container.put("checkUpdates", checkUpdates);
container.put("currentPlaylist", "TODO"); // proposed feature: store separate mod lists in lists/ to load/save later?
try {
Files.write(Paths.get(System.getProperty("user.home") + "/.firestar/firestar.conf"), container.toString().getBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void loadConf(){
try {
JSONObject container = new JSONObject(new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "/.firestar/firestar.conf"))));
System.out.println(container.toString()); // debug
confvint = (int) container.get("version"); // used for converting configs between program versions later down the line
outpath = container.get("2048path").toString();
repatch = (boolean) container.get("safemode");
windows = (boolean) container.get("isWin32");
try {
checkUpdates = (boolean) container.get("checkUpdates");
} catch (JSONException e) {
checkUpdates = true;
}
} catch (IOException e) {
System.out.println("ERROR: Failed to load firestar.conf");
System.out.println(e.getMessage());
}
}
public static void loadConf(MissPiggy w){
try {
JSONObject container = new JSONObject(new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "/.firestar/firestar.conf"))));
System.out.println(container.toString()); // debug
confvint = (int) container.get("version"); // used for converting configs between program versions later down the line
outpath = container.get("2048path").toString();
repatch = (boolean) container.get("safemode");
windows = (boolean) container.get("isWin32");
try {
checkUpdates = (boolean) container.get("checkUpdates");
} catch (JSONException e) {
checkUpdates = true;
}
} catch (Exception e) {
JOptionPane.showMessageDialog(w.frame, "Firestar couldn't load your config file. Tread lightly.\n\n" + e.getMessage(), "Critical Error", JOptionPane.ERROR_MESSAGE);
System.out.println("ERROR: Failed to load firestar.conf");
System.out.println(e.getMessage());
}
}
public static void deleteDir(File file) { // https://stackoverflow.com/a/29175213/9259829
File[] contents = file.listFiles();
if (contents != null) {
for (File f : contents) {
if (! Files.isSymbolicLink(f.toPath())) {
deleteDir(f);
}
}
}
file.delete();
}
public static void downloadDependenciesBeforeSetVisible(JFrame invoker) {
invoker.setVisible(false);
Main.downloadDependencies();
invoker.setVisible(true);
confvint = vint;
Main.writeConf();
}
public static boolean downloadDependencies () { // todo: CHECKSUM!!!! THESE ARE EXECUTABLES!!!!!!!!!!! DON'T ALLOW MALWARE!!!!
boolean downloader = new Fozzie().DownloadFile("https://bonkmaykr.worlio.com/http/firestar/firesdk.zip", System.getProperty("user.home") + "/.firestar/", "firesdk.zip");
if (!downloader) {return false;}
ZipFile sdk = new ZipFile(System.getProperty("user.home") + "/.firestar/firesdk.zip");
try {
sdk.extractAll(System.getProperty("user.home") + "/.firestar/");
} catch (ZipException e) {
JOptionPane.showMessageDialog(new JFrame(), e.getMessage(), "Critical Error", JOptionPane.ERROR_MESSAGE);
System.out.println(e.getMessage());
return false;
}
sdk.getFile().delete(); // cleanup
return true;
}
public static boolean callDownloaderStatically (String url, String folder, String name) {
return new Fozzie().DownloadFile(url, folder, name);
}
public static Process exec(String[] cmd, String cwd) throws IOException {
Process p;
String[] pcmd;
if (!Main.windows) {
pcmd = new String[cmd.length + 1];
pcmd[0] = "wine";
System.arraycopy(cmd, 0, pcmd, 1, cmd.length);
p = Runtime.getRuntime().exec(pcmd, null, new File(cwd));
} else {
p = Runtime.getRuntime().exec(cmd, null, new File(cwd.replace("/", "\\")));
@Override
public String toString() {
return value;
}
}
public enum ArcKey { // decryption keys for 2048, type used by downloader
BASE("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
LATEST("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
ADDON_HD("KO5ifR1dQ+eHBlgi6TI0Bdnv4uNsGG5kYGIR4Ojs7ejuis9/anXfuudVNvzgdu+9z1z+asJojA9uAACgRhTl"),
ADDON_HD_FURY("KO5ifR1dQ+eHBlgi6TI0Bdnv4uNsFG5kYGIR4Ojs7ejuis9/3fydBRm3eCJX7biz/vVTm/2jMT64AQCCYhVy");
private final String value;
ArcKey(final String value) {this.value = value;}
@Override
public String toString() {
return value;
}
}
public class Mod {
public String path; // file name
public int version = 1;
public int priority = 0; //unused
public String friendlyName;
public String description = "";
public String game; //TODO for multi game support
public int loaderversion = 0; //minimum required vint or feature level from Firestar
public String author; // if null, "Author is unknown."
public boolean enabled = true;
public List<boolean[]> requires = new ArrayList<>(); // TODO: load optional "requires" array from mod meta if it exists. it will be base, patches, hd dlc, and fury dlc in that order.
// TODO: save 'false true false false' in ost gen if necessary (patches change localization)
}
// Mods
public static List<Mod> Mods = new ArrayList<Mod>();
// UI Global Assets
public static Font fExo2;
public static BufferedImage windowIcon;
public static void main(String[] args) {
// license string
System.out.printf("FIRESTAR MOD MANAGER for WipEout 2048\nversion " + vstr + " (codename " + vcode + ") major " + vint + "\n" +
"JVM host appears to be " + System.getProperty("os.name") +
"\nRunning from " + System.getProperty("user.dir") +
"\nCopyright (C) 2024 bonkmaykr\n\nThis program is free software: you can redistribute it and/or modify\n" +
"it under the terms of the GNU General Public License as published by\n" +
"the Free Software Foundation, either version 3 of the License, or\n" +
"(at your option) any later version.\n" +
"\n" +
"This program is distributed in the hope that it will be useful,\n" +
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +
"GNU General Public License for more details.\n" +
"\n" +
"You should have received a copy of the GNU General Public License\n" +
"along with this program. If not, see https://www.gnu.org/licenses/.\n\n\n\n");
//begin
// load global assets
try {
fExo2 = Font.createFont(Font.TRUETYPE_FONT, Main.class.getResourceAsStream("/exo2.ttf"));
} catch (Exception e) {
System.out.println("Font \"Exo 2\" is missing!");
fExo2 = new Font("Arial", Font.PLAIN, 12);
}
// load global window icon
try {
windowIcon = ImageIO.read(Main.class.getResourceAsStream("/titleIcon.png"));
} catch (IOException e) {
System.out.println("ERROR: Failed to find titleIcon.png. Window will not have an icon.");
}
// check and load configs
File fConf = new File(System.getProperty("user.home") + "/.firestar/firestar.conf");
if (!fConf.isFile()) {
System.out.println("No configuration was found. Starting the initial setup");
new WilkinsCoffee().setup();
} else {
new MissPiggy().Action(); // Quick! Start singing Firework by Katy Perry! (or open the main window i guess...)
}
}
public static void writeConf(){
JSONObject container = new JSONObject();
container.put("version", vint);
container.put("2048path", outpath);
container.put("HDpath", "TODO"); // proposed hd/fury support for ps3, will use very simplified Fast Mode due to less difficulty installing
container.put("safemode", repatch);
container.put("isWin32", windows);
container.put("checkUpdates", checkUpdates);
container.put("currentPlaylist", "TODO"); // proposed feature: store separate mod lists in lists/ to load/save later?
try {
Files.write(Paths.get(System.getProperty("user.home") + "/.firestar/firestar.conf"), container.toString().getBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void loadConf(){
try {
JSONObject container = new JSONObject(new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "/.firestar/firestar.conf"))));
System.out.println(container.toString()); // debug
confvint = (int) container.get("version"); // used for converting configs between program versions later down the line
outpath = container.get("2048path").toString();
repatch = (boolean) container.get("safemode");
windows = (boolean) container.get("isWin32");
try {
checkUpdates = (boolean) container.get("checkUpdates");
} catch (JSONException e) {
checkUpdates = true;
}
} catch (IOException e) {
System.out.println("ERROR: Failed to load firestar.conf");
System.out.println(e.getMessage());
}
}
public static void loadConf(MissPiggy w){
try {
JSONObject container = new JSONObject(new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "/.firestar/firestar.conf"))));
System.out.println(container.toString()); // debug
confvint = (int) container.get("version"); // used for converting configs between program versions later down the line
outpath = container.get("2048path").toString();
repatch = (boolean) container.get("safemode");
windows = (boolean) container.get("isWin32");
try {
checkUpdates = (boolean) container.get("checkUpdates");
} catch (JSONException e) {
checkUpdates = true;
}
} catch (Exception e) {
JOptionPane.showMessageDialog(w.frame, "Firestar couldn't load your config file. Tread lightly.\n\n" + e.getMessage(), "Critical Error", JOptionPane.ERROR_MESSAGE);
System.out.println("ERROR: Failed to load firestar.conf");
System.out.println(e.getMessage());
}
}
public static void deleteDir(File file) { // https://stackoverflow.com/a/29175213/9259829
File[] contents = file.listFiles();
if (contents != null) {
for (File f : contents) {
if (! Files.isSymbolicLink(f.toPath())) {
deleteDir(f);
}
}
}
file.delete();
}
public static void downloadDependenciesBeforeSetVisible(JFrame invoker) {
invoker.setVisible(false);
Main.downloadDependencies();
invoker.setVisible(true);
confvint = vint;
Main.writeConf();
}
public static boolean downloadDependencies () { // todo: CHECKSUM!!!! THESE ARE EXECUTABLES!!!!!!!!!!! DON'T ALLOW MALWARE!!!!
boolean downloader = new Fozzie().DownloadFile("https://bonkmaykr.worlio.com/http/firestar/firesdk.zip", System.getProperty("user.home") + "/.firestar/", "firesdk.zip");
if (!downloader) {return false;}
ZipFile sdk = new ZipFile(System.getProperty("user.home") + "/.firestar/firesdk.zip");
try {
sdk.extractAll(System.getProperty("user.home") + "/.firestar/");
} catch (ZipException e) {
JOptionPane.showMessageDialog(new JFrame(), e.getMessage(), "Critical Error", JOptionPane.ERROR_MESSAGE);
System.out.println(e.getMessage());
return false;
}
sdk.getFile().delete(); // cleanup
return true;
}
public static boolean callDownloaderStatically (String url, String folder, String name) {
return new Fozzie().DownloadFile(url, folder, name);
}
public static Process exec(String[] cmd, String cwd) throws IOException {
Process p;
String[] pcmd;
if (!Main.windows) {
pcmd = new String[cmd.length + 1];
pcmd[0] = "wine";
System.arraycopy(cmd, 0, pcmd, 1, cmd.length);
p = Runtime.getRuntime().exec(pcmd, null, new File(cwd));
} else {
p = Runtime.getRuntime().exec(cmd, null, new File(cwd.replace("/", "\\")));
}
return p;
}
return p;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -5,133 +5,132 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
/**
* Created by simon on 8/29/17.
* Copyright 2017 Simon Haoran Liang
/*
* Created by simon on 8/29/17.
* Copyright 2017 Simon Haoran Liang
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
* following conditions:
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
public class ReplacingInputStream extends FilterInputStream {
private Queue<Integer> inQueue, outQueue;
private final byte[] search, replacement;
private boolean caseSensitive = true;
private Queue<Integer> inQueue, outQueue;
private final byte[] search, replacement;
private boolean caseSensitive = true;
public ReplacingInputStream(InputStream in, String search, String replacement) {
super(in);
public ReplacingInputStream(InputStream in, String search, String replacement) {
super(in);
this.inQueue = new LinkedList<>();
this.outQueue = new LinkedList<>();
this.inQueue = new LinkedList<>();
this.outQueue = new LinkedList<>();
this.search = search.getBytes();
this.replacement = replacement.getBytes();
}
this.search = search.getBytes();
this.replacement = replacement.getBytes();
}
public ReplacingInputStream(InputStream in, String search, String replacement, boolean caseSensitive) {
super(in);
public ReplacingInputStream(InputStream in, String search, String replacement, boolean caseSensitive) {
super(in);
this.inQueue = new LinkedList<>();
this.outQueue = new LinkedList<>();
this.inQueue = new LinkedList<>();
this.outQueue = new LinkedList<>();
this.search = search.getBytes();
this.replacement = replacement.getBytes();
this.caseSensitive = caseSensitive;
}
this.search = search.getBytes();
this.replacement = replacement.getBytes();
this.caseSensitive = caseSensitive;
}
private boolean isMatchFound() {
Iterator<Integer> iterator = inQueue.iterator();
private boolean isMatchFound() {
Iterator<Integer> iterator = inQueue.iterator();
for (byte b : search) {
if (!iterator.hasNext()) return false;
Integer i = iterator.next();
if (caseSensitive && b != i) return false;
else if (Character.toLowerCase(b) != Character.toLowerCase(i.byteValue())) return false;
}
for (byte b : search) {
if (!iterator.hasNext()) return false;
Integer i = iterator.next();
if (caseSensitive && b != i) return false;
else if (Character.toLowerCase(b) != Character.toLowerCase(i.byteValue())) return false;
}
return true;
}
return true;
}
private void readAhead() throws IOException {
// Work up some look-ahead.
while (inQueue.size() < search.length) {
int next = super.read();
inQueue.offer(next);
private void readAhead() throws IOException {
// Work up some look-ahead.
while (inQueue.size() < search.length) {
int next = super.read();
inQueue.offer(next);
if (next == -1) {
break;
}
}
}
if (next == -1) {
break;
}
}
}
@Override
public int read() throws IOException {
// Next byte already determined.
@Override
public int read() throws IOException {
// Next byte already determined.
while (outQueue.isEmpty()) {
readAhead();
while (outQueue.isEmpty()) {
readAhead();
if (isMatchFound()) {
for (byte a : search) {
inQueue.remove();
}
if (isMatchFound()) {
for (byte a : search) {
inQueue.remove();
}
for (byte b : replacement) {
outQueue.offer((int) b);
}
} else {
outQueue.add(inQueue.remove());
}
}
for (byte b : replacement) {
outQueue.offer((int) b);
}
} else {
outQueue.add(inQueue.remove());
}
}
return outQueue.remove();
}
return outQueue.remove();
}
@Override
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
@Override
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
// copied straight from InputStream inplementation, just needed to to use `read()` from this class
@Override
public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
// copied straight from InputStream inplementation, just needed to to use `read()` from this class
@Override
public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) {
}
return i;
}
int i = 1;
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) { }
return i;
}
}

View File

@ -56,397 +56,397 @@ import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class Rizzo {
private Scanner scanner;
private final int maxVer = 1;
private int ver = 1;
private String workingDir;
private Scanner scanner;
private final int maxVer = 1;
private int ver = 1;
private String workingDir;
public Rizzo(InputStream infile, String workingDir) throws FileNotFoundException, FirescriptFormatException {
if (!workingDir.endsWith("/")) this.workingDir = workingDir + "/";
else this.workingDir = workingDir;
scanner = new Scanner(infile);
parseScript(null);
}
private void parseScript(Object context) throws FirescriptFormatException {
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.startsWith("#") || line.length() < 1) continue;
if (!parseArgs(translateCommandline(line), context)) break;
public Rizzo(InputStream infile, String workingDir) throws FileNotFoundException, FirescriptFormatException {
if (!workingDir.endsWith("/")) this.workingDir = workingDir + "/";
else this.workingDir = workingDir;
scanner = new Scanner(infile);
parseScript(null);
}
}
private boolean parseArgs(String[] args, Object context) throws FirescriptFormatException {
System.out.println("Parsing Command: " + Arrays.toString(args));
if (args.length > 0) {
if (context == null) {
if (args[0].equalsIgnoreCase("fscript")) {
ver = Integer.parseInt(args[1]); // We'll do shit with this later
if (ver > maxVer) throw new FirescriptFormatException(args[0], "script too new");
} else if (args[0].equalsIgnoreCase("file")) {
File newCtx = new File(workingDir + args[1]);
System.out.println("Calling new parse: " + Arrays.toString(Arrays.copyOfRange(args, 2, args.length)));
parseArgs(Arrays.copyOfRange(args, 2, args.length), newCtx);
} else throw new FirescriptFormatException("fscript", "unknown command '" + args[0] + "'");
} else {
System.out.println("Using context: " + context.getClass().getName() + "@" + context.hashCode());
if (args[0].equals("{")) {
System.out.println("New context block: " + context.getClass().getName() + "@" + context.hashCode());
parseScript(context);
} else if (args[0].equals("}")) {
System.out.println("Ending context block: " + context.getClass().getName() + "@" + context.hashCode());
return false;
} else if (context instanceof File file) {
if (file.exists()) {
if (args[0].equalsIgnoreCase("delete")) {
System.out.println("Deleting: " + file.getPath());
if (file.getAbsolutePath().startsWith(workingDir)) {
if (file.isDirectory()) Main.deleteDir(file);
else file.delete();
}
} else if (args[0].equalsIgnoreCase("xml")) {
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// Mmmm, love me some INVALID XML corrections.
ReplacingInputStream ris = new ReplacingInputStream(new ReplacingInputStream(new ReplacingInputStream(new FileInputStream(file), "\r\n", ""), "&", "&amp;"), "\n", "&#10;");
Document doc = docBuilder.parse(ris);
parseArgs(Arrays.copyOfRange(args, 1, args.length), doc);
try {
FileOutputStream output = new FileOutputStream(file);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
private void parseScript(Object context) throws FirescriptFormatException {
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.startsWith("#") || line.length() < 1) continue;
if (!parseArgs(translateCommandline(line), context)) break;
}
}
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
private boolean parseArgs(String[] args, Object context) throws FirescriptFormatException {
System.out.println("Parsing Command: " + Arrays.toString(args));
if (args.length > 0) {
if (context == null) {
if (args[0].equalsIgnoreCase("fscript")) {
ver = Integer.parseInt(args[1]); // We'll do shit with this later
if (ver > maxVer) throw new FirescriptFormatException(args[0], "script too new");
} else if (args[0].equalsIgnoreCase("file")) {
File newCtx = new File(workingDir + args[1]);
System.out.println("Calling new parse: " + Arrays.toString(Arrays.copyOfRange(args, 2, args.length)));
parseArgs(Arrays.copyOfRange(args, 2, args.length), newCtx);
} else throw new FirescriptFormatException("fscript", "unknown command '" + args[0] + "'");
} else {
System.out.println("Using context: " + context.getClass().getName() + "@" + context.hashCode());
if (args[0].equals("{")) {
System.out.println("New context block: " + context.getClass().getName() + "@" + context.hashCode());
parseScript(context);
} else if (args[0].equals("}")) {
System.out.println("Ending context block: " + context.getClass().getName() + "@" + context.hashCode());
return false;
} else if (context instanceof File file) {
if (file.exists()) {
if (args[0].equalsIgnoreCase("delete")) {
System.out.println("Deleting: " + file.getPath());
if (file.getAbsolutePath().startsWith(workingDir)) {
if (file.isDirectory()) Main.deleteDir(file);
else file.delete();
}
} else if (args[0].equalsIgnoreCase("xml")) {
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// Mmmm, love me some INVALID XML corrections.
ReplacingInputStream ris = new ReplacingInputStream(new ReplacingInputStream(new ReplacingInputStream(new FileInputStream(file), "\r\n", ""), "&", "&amp;"), "\n", "&#10;");
Document doc = docBuilder.parse(ris);
parseArgs(Arrays.copyOfRange(args, 1, args.length), doc);
try {
FileOutputStream output = new FileOutputStream(file);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(source, result);
// Look ma, I'm breaking XML standards!
String xmlString = result.getWriter().toString()
.replace("&amp;", "&")
.replace("&#9;", "\t")
.replace("&#8;", "\b")
.replace("&#10;", "\n")
.replace("&#13;", "\r")
.replace("&#12;", "\f");
try (PrintStream ps = new PrintStream(output)) {
ps.print(xmlString);
}
} catch (TransformerException ex) {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (SAXException | IOException | ParserConfigurationException ex) {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
}
} else if (args[0].equalsIgnoreCase("str") || args[0].equalsIgnoreCase("xstr")) {
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayInputStream bais = new ByteArrayInputStream(fis.readAllBytes());
fis.close();
FileOutputStream fos = new FileOutputStream(file);
if (args[1].equalsIgnoreCase("append")) {
bais.transferTo(fos);
for (int s = 0; s < args[2].length(); s++) {
char c = args[2].charAt(s);
fos.write(c);
}
} else if (args[1].equalsIgnoreCase("replace") || args[1].equalsIgnoreCase("delete")) {
String replacement = "";
if (args[1].equalsIgnoreCase("replace")) replacement = args[3];
ReplacingInputStream ris;
if (args[0].equalsIgnoreCase("xstr")) ris = new ReplacingInputStream(bais, args[2], replacement, false);
else ris = new ReplacingInputStream(bais, args[2], replacement);
ris.transferTo(fos);
ris.close();
}
fos.flush();
fos.close();
} catch (IOException ex) {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
}
} else if (args[0].equalsIgnoreCase("binedit")) {
int offset = Integer.parseInt(args[1]);
String bytes = args[2];
if (bytes.length() % 2 != 0) throw new FirescriptFormatException(args[0], "invalid length of bytes");
try {
byte[] ba;
try (FileInputStream fis = new FileInputStream(file)) {
ba = fis.readAllBytes();
}
if (offset >= ba.length) throw new FirescriptFormatException(args[0], "offset is larger than file size");
else {
byte[] in = HexFormat.of().parseHex(bytes);
System.arraycopy(in, 0, ba, offset, in.length);
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(ba);
fos.flush();
}
}
} catch (IOException ex) {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
}
} else if (args[0].equalsIgnoreCase("patch")) {
try {
List<String> original = Files.readAllLines(file.toPath());
File patchFile = new File(workingDir + args[1]);
if (!patchFile.exists()) throw new FirescriptFormatException(args[0], "patch file doesn't exist");
List<String> patched = Files.readAllLines(patchFile.toPath());
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
Patch<String> patch = UnifiedDiffUtils.parseUnifiedDiff(patched);
List<String> result = DiffUtils.patch(original, patch);
transformer.transform(source, result);
// Look ma, I'm breaking XML standards!
String xmlString = result.getWriter().toString()
.replace("&amp;", "&")
.replace("&#9;", "\t")
.replace("&#8;", "\b")
.replace("&#10;", "\n")
.replace("&#13;", "\r")
.replace("&#12;", "\f");
try (PrintStream ps = new PrintStream(output)) {
ps.print(xmlString);
}
} catch (TransformerException ex) {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (SAXException | IOException | ParserConfigurationException ex) {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
}
} else if (args[0].equalsIgnoreCase("str") || args[0].equalsIgnoreCase("xstr")) {
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayInputStream bais = new ByteArrayInputStream(fis.readAllBytes());
fis.close();
FileOutputStream fos = new FileOutputStream(file);
if (args[1].equalsIgnoreCase("append")) {
bais.transferTo(fos);
for (int s = 0; s < args[2].length(); s++) {
char c = args[2].charAt(s);
fos.write(c);
}
} else if (args[1].equalsIgnoreCase("replace") || args[1].equalsIgnoreCase("delete")) {
String replacement = "";
if (args[1].equalsIgnoreCase("replace")) replacement = args[3];
ReplacingInputStream ris;
if (args[0].equalsIgnoreCase("xstr")) ris = new ReplacingInputStream(bais, args[2], replacement, false);
else ris = new ReplacingInputStream(bais, args[2], replacement);
ris.transferTo(fos);
ris.close();
}
fos.flush();
fos.close();
} catch (IOException ex) {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
}
} else if (args[0].equalsIgnoreCase("binedit")) {
int offset = Integer.parseInt(args[1]);
String bytes = args[2];
if (bytes.length() % 2 != 0) throw new FirescriptFormatException(args[0], "invalid length of bytes");
try {
byte[] ba;
try (FileInputStream fis = new FileInputStream(file)) {
ba = fis.readAllBytes();
}
if (offset >= ba.length) throw new FirescriptFormatException(args[0], "offset is larger than file size");
else {
byte[] in = HexFormat.of().parseHex(bytes);
System.arraycopy(in, 0, ba, offset, in.length);
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(ba);
fos.flush();
}
}
} catch (IOException ex) {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
}
} else if (args[0].equalsIgnoreCase("patch")) {
try {
List<String> original = Files.readAllLines(file.toPath());
File patchFile = new File(workingDir + args[1]);
if (!patchFile.exists()) throw new FirescriptFormatException(args[0], "patch file doesn't exist");
List<String> patched = Files.readAllLines(patchFile.toPath());
try (FileWriter fileWriter = new FileWriter(file)) {
for (String str : result) {
fileWriter.write(str + "\r\n");
}
}
} catch (FirescriptFormatException | PatchFailedException | IOException ex) {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
}
} else throw new FirescriptFormatException("file", "unknown command '" + args[0] + "'");
} else System.out.println("fscript: file context not found, skipping.");
} else if (context instanceof Document document) {
if (args[0].equalsIgnoreCase("modify")) {
Element elem = (Element)traverse(document, args[1]);
parseArgs(Arrays.copyOfRange(args, 2, args.length), elem);
} else if (args[0].equalsIgnoreCase("create")) {
String newTag = args[1].substring(args[1].lastIndexOf(".")+1);
String newID = "";
if (newTag.contains("#")) {
newID = newTag.substring(newTag.indexOf("#")+1);
newTag = newTag.substring(0, newTag.indexOf("#"));
Patch<String> patch = UnifiedDiffUtils.parseUnifiedDiff(patched);
List<String> result = DiffUtils.patch(original, patch);
try (FileWriter fileWriter = new FileWriter(file)) {
for (String str : result) {
fileWriter.write(str + "\r\n");
}
}
} catch (FirescriptFormatException | PatchFailedException | IOException ex) {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
}
} else throw new FirescriptFormatException("file", "unknown command '" + args[0] + "'");
} else System.out.println("fscript: file context not found, skipping.");
} else if (context instanceof Document document) {
if (args[0].equalsIgnoreCase("modify")) {
Element elem = (Element)traverse(document, args[1]);
parseArgs(Arrays.copyOfRange(args, 2, args.length), elem);
} else if (args[0].equalsIgnoreCase("create")) {
String newTag = args[1].substring(args[1].lastIndexOf(".")+1);
String newID = "";
if (newTag.contains("#")) {
newID = newTag.substring(newTag.indexOf("#")+1);
newTag = newTag.substring(0, newTag.indexOf("#"));
}
Element newElem = document.createElement(newTag);
if (newID != null && newID.length() > 0) newElem.setAttribute("id", newID);
traverse(document, args[1].substring(0, args[1].lastIndexOf("."))).appendChild(newElem);
parseArgs(Arrays.copyOfRange(args, 2, args.length), newElem);
} else if (args[0].equalsIgnoreCase("delete")) {
Element elem = (Element)traverse(document, args[1]);
elem.getParentNode().removeChild(elem);
} else if (args[0].equalsIgnoreCase("merge")) {
// We're basically copying the file context xml command but with another xml document.
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
ReplacingInputStream ris = new ReplacingInputStream(new ReplacingInputStream(new ReplacingInputStream(new FileInputStream(new File(workingDir + args[1])), "\r\n", ""), "&", "&amp;"), "\n", "&#10;");
Document outDoc = docBuilder.parse(ris);
NamedNodeMap nnm = outDoc.getDocumentElement().getAttributes();
for (int x = 0; x < nnm.getLength(); x++) {
Attr importedNode = (Attr) document.importNode(nnm.item(x), true);
document.getDocumentElement().setAttributeNodeNS(importedNode);
}
NodeList cn = outDoc.getDocumentElement().getChildNodes();
for (int x = 0; x < cn.getLength(); x++) {
Node importedNode = document.importNode(cn.item(x), true);
document.getDocumentElement().appendChild(importedNode);
}
} catch (SAXException | IOException | ParserConfigurationException ex) {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
}
} else throw new FirescriptFormatException("xml", "unknown command '" + args[0] + "'");
} else if (context instanceof Element element) {
if (args[0].equalsIgnoreCase("set")) {
if (args[1].equalsIgnoreCase("attribute"))
// We replace newlines on XML write.
element.setAttribute(args[2], args[3].replace("\\n", "&#10;"));
else if (args[1].equalsIgnoreCase("value"))
element.setNodeValue(args[2]);
} else if (args[0].equalsIgnoreCase("create")) {
String finalTag = args[1];
String path = "";
if (finalTag.lastIndexOf(".") > 0) {
path = args[1].substring(0, finalTag.lastIndexOf("."));
finalTag = args[1].substring(finalTag.lastIndexOf(".")+1);
}
String id = "";
String name = "";
if (finalTag.contains("#")) {
id = finalTag.substring(finalTag.indexOf("#")+1);
finalTag = finalTag.substring(0, finalTag.indexOf("#"));
} else if (finalTag.contains("$")) {
name = finalTag.substring(finalTag.indexOf("$")+1);
finalTag = finalTag.substring(0, finalTag.indexOf("$"));
}
Element finalElem = element.getOwnerDocument().createElement(finalTag);
if (id != null && id.length() > 0) finalElem.setAttribute("id", id);
if (name != null && name.length() > 0) finalElem.setAttribute("name", name);
traverse(element, path).appendChild(finalElem);
parseArgs(Arrays.copyOfRange(args, 2, args.length), finalElem);
} else if (args[0].equalsIgnoreCase("create-at")) {
int index = Integer.parseInt(args[1]);
String finalTag = args[2];
String id = "";
String name = "";
if (finalTag.contains("#")) {
id = finalTag.substring(finalTag.indexOf("#")+1);
finalTag = finalTag.substring(0, finalTag.indexOf("#"));
} else if (finalTag.contains("$")) {
name = finalTag.substring(finalTag.indexOf("$")+1);
finalTag = finalTag.substring(0, finalTag.indexOf("$"));
}
Element finalElem = element.getOwnerDocument().createElement(finalTag);
if (id != null && id.length() > 0) finalElem.setAttribute("id", id);
if (name != null && name.length() > 0) finalElem.setAttribute("name", name);
element.insertBefore(finalElem, element.getChildNodes().item(index));
parseArgs(Arrays.copyOfRange(args, 3, args.length), finalElem);
} else throw new FirescriptFormatException("xml", "unknown element command '" + args[0] + "'");
} else throw new FirescriptFormatException("context is unknown");
}
Element newElem = document.createElement(newTag);
if (newID != null && newID.length() > 0) newElem.setAttribute("id", newID);
traverse(document, args[1].substring(0, args[1].lastIndexOf("."))).appendChild(newElem);
parseArgs(Arrays.copyOfRange(args, 2, args.length), newElem);
} else if (args[0].equalsIgnoreCase("delete")) {
Element elem = (Element)traverse(document, args[1]);
elem.getParentNode().removeChild(elem);
} else if (args[0].equalsIgnoreCase("merge")) {
// We're basically copying the file context xml command but with another xml document.
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
ReplacingInputStream ris = new ReplacingInputStream(new ReplacingInputStream(new ReplacingInputStream(new FileInputStream(new File(workingDir + args[1])), "\r\n", ""), "&", "&amp;"), "\n", "&#10;");
Document outDoc = docBuilder.parse(ris);
}
return true;
}
NamedNodeMap nnm = outDoc.getDocumentElement().getAttributes();
for (int x = 0; x < nnm.getLength(); x++) {
Attr importedNode = (Attr) document.importNode(nnm.item(x), true);
document.getDocumentElement().setAttributeNodeNS(importedNode);
}
private Node traverse(Node owner, String selector) throws FirescriptFormatException {
if (selector == null || selector.length() == 0 || owner == null) {
return owner;
}
String[] elems = selector.split("\\.");
Node parent = owner;
for (String tag : elems) {
Node newParent = null;
int index = 0;
if (tag.contains("[")) {
index = Integer.parseInt(tag.substring(tag.indexOf("[")+1, tag.lastIndexOf("]")));
tag = tag.substring(0, tag.indexOf("["));
}
NodeList cn = outDoc.getDocumentElement().getChildNodes();
for (int x = 0; x < cn.getLength(); x++) {
Node importedNode = document.importNode(cn.item(x), true);
document.getDocumentElement().appendChild(importedNode);
}
} catch (SAXException | IOException | ParserConfigurationException ex) {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
}
} else throw new FirescriptFormatException("xml", "unknown command '" + args[0] + "'");
} else if (context instanceof Element element) {
if (args[0].equalsIgnoreCase("set")) {
if (args[1].equalsIgnoreCase("attribute"))
// We replace newlines on XML write.
element.setAttribute(args[2], args[3].replace("\\n", "&#10;"));
else if (args[1].equalsIgnoreCase("value"))
element.setNodeValue(args[2]);
} else if (args[0].equalsIgnoreCase("create")) {
String finalTag = args[1];
String path = "";
if (finalTag.lastIndexOf(".") > 0) {
path = args[1].substring(0, finalTag.lastIndexOf("."));
finalTag = args[1].substring(finalTag.lastIndexOf(".")+1);
}
String id = "";
if (tag.contains("#")) {
id = tag.substring(tag.indexOf("#")+1);
tag = tag.substring(0, tag.indexOf("#"));
}
String name = "";
if (finalTag.contains("#")) {
id = finalTag.substring(finalTag.indexOf("#")+1);
finalTag = finalTag.substring(0, finalTag.indexOf("#"));
} else if (finalTag.contains("$")) {
name = finalTag.substring(finalTag.indexOf("$")+1);
finalTag = finalTag.substring(0, finalTag.indexOf("$"));
if (tag.contains("$")) {
name = tag.substring(tag.indexOf("$")+1);
tag = tag.substring(0, tag.indexOf("$"));
}
Element finalElem = element.getOwnerDocument().createElement(finalTag);
if (id != null && id.length() > 0) finalElem.setAttribute("id", id);
if (name != null && name.length() > 0) finalElem.setAttribute("name", name);
traverse(element, path).appendChild(finalElem);
parseArgs(Arrays.copyOfRange(args, 2, args.length), finalElem);
} else if (args[0].equalsIgnoreCase("create-at")) {
int index = Integer.parseInt(args[1]);
String finalTag = args[2];
String id = "";
String name = "";
if (finalTag.contains("#")) {
id = finalTag.substring(finalTag.indexOf("#")+1);
finalTag = finalTag.substring(0, finalTag.indexOf("#"));
} else if (finalTag.contains("$")) {
name = finalTag.substring(finalTag.indexOf("$")+1);
finalTag = finalTag.substring(0, finalTag.indexOf("$"));
if (id.length() > 0) {
NodeList ns;
if (parent instanceof Document document)
ns = document.getElementsByTagName(tag);
else
ns = ((Element)parent).getElementsByTagName(tag);
for (int i = 0; i < ns.getLength(); i++) {
Node n = ns.item(i);
if (n.getNodeName().equals("#text")) continue;
if (((Element)n).getAttribute("id").equals(id)) {
newParent = (Element)n;
break;
}
}
} else if (name.length() > 0) {
NodeList ns;
if (parent instanceof Document document)
ns = document.getChildNodes();
else
ns = ((Element)parent).getChildNodes();
for (int i = 0; i < ns.getLength(); i++) {
Node n = ns.item(i);
if (n.getNodeName().equals("#text")) continue;
if (((Element)n).getAttribute("name").equals(name)) {
newParent = (Element)n;
break;
}
}
} else {
if (parent instanceof Document document)
newParent = document.getElementsByTagName(tag).item(index);
else
newParent = ((Element)parent).getElementsByTagName(tag).item(index);
}
Element finalElem = element.getOwnerDocument().createElement(finalTag);
if (id != null && id.length() > 0) finalElem.setAttribute("id", id);
if (name != null && name.length() > 0) finalElem.setAttribute("name", name);
element.insertBefore(finalElem, element.getChildNodes().item(index));
parseArgs(Arrays.copyOfRange(args, 3, args.length), finalElem);
} else throw new FirescriptFormatException("xml", "unknown element command '" + args[0] + "'");
} else throw new FirescriptFormatException("context is unknown");
}
}
return true;
}
private Node traverse(Node owner, String selector) throws FirescriptFormatException {
if (selector == null || selector.length() == 0 || owner == null) {
return owner;
}
String[] elems = selector.split("\\.");
Node parent = owner;
for (String tag : elems) {
Node newParent = null;
int index = 0;
if (tag.contains("[")) {
index = Integer.parseInt(tag.substring(tag.indexOf("[")+1, tag.lastIndexOf("]")));
tag = tag.substring(0, tag.indexOf("["));
}
String id = "";
if (tag.contains("#")) {
id = tag.substring(tag.indexOf("#")+1);
tag = tag.substring(0, tag.indexOf("#"));
}
String name = "";
if (tag.contains("$")) {
name = tag.substring(tag.indexOf("$")+1);
tag = tag.substring(0, tag.indexOf("$"));
}
if (id.length() > 0) {
NodeList ns;
if (parent instanceof Document document)
ns = document.getElementsByTagName(tag);
else
ns = ((Element)parent).getElementsByTagName(tag);
for (int i = 0; i < ns.getLength(); i++) {
Node n = ns.item(i);
if (n.getNodeName().equals("#text")) continue;
if (((Element)n).getAttribute("id").equals(id)) {
newParent = (Element)n;
break;
}
if (newParent == null) throw new FirescriptFormatException("xml: selector is invalid");
else parent = newParent;
}
} else if (name.length() > 0) {
NodeList ns;
if (parent instanceof Document document)
ns = document.getChildNodes();
else
ns = ((Element)parent).getChildNodes();
for (int i = 0; i < ns.getLength(); i++) {
Node n = ns.item(i);
if (n.getNodeName().equals("#text")) continue;
if (((Element)n).getAttribute("name").equals(name)) {
newParent = (Element)n;
break;
}
}
} else {
if (parent instanceof Document document)
newParent = document.getElementsByTagName(tag).item(index);
else
newParent = ((Element)parent).getElementsByTagName(tag).item(index);
}
if (newParent == null) throw new FirescriptFormatException("xml: selector is invalid");
else parent = newParent;
}
return parent;
}
private static String[] translateCommandline(String line) throws FirescriptFormatException {
if (line == null || line.length() == 0) {
return new String[0];
return parent;
}
final int normal = 0;
final int inQuote = 1;
final int inDoubleQuote = 2;
int state = normal;
final ArrayList<String> result = new ArrayList<String>();
final StringBuilder current = new StringBuilder();
boolean lastTokenHasBeenQuoted = false;
boolean lastTokenWasEscaped = false;
private static String[] translateCommandline(String line) throws FirescriptFormatException {
if (line == null || line.length() == 0) {
return new String[0];
}
for (int i = 0; i < line.length(); i++) {
char nextTok = line.charAt(i);
switch (state) {
case inQuote -> {
if (nextTok == '\\') {
lastTokenWasEscaped = true;
} else if (nextTok == '\'' && !lastTokenWasEscaped) {
lastTokenHasBeenQuoted = true;
state = normal;
} else {
if (lastTokenWasEscaped) {
if (nextTok == 't') nextTok = '\t';
if (nextTok == 'b') nextTok = '\b';
if (nextTok == 'n') nextTok = '\n';
if (nextTok == 'r') nextTok = '\r';
if (nextTok == 'f') nextTok = '\f';
final int normal = 0;
final int inQuote = 1;
final int inDoubleQuote = 2;
int state = normal;
final ArrayList<String> result = new ArrayList<String>();
final StringBuilder current = new StringBuilder();
boolean lastTokenHasBeenQuoted = false;
boolean lastTokenWasEscaped = false;
for (int i = 0; i < line.length(); i++) {
char nextTok = line.charAt(i);
switch (state) {
case inQuote -> {
if (nextTok == '\\') {
lastTokenWasEscaped = true;
} else if (nextTok == '\'' && !lastTokenWasEscaped) {
lastTokenHasBeenQuoted = true;
state = normal;
} else {
if (lastTokenWasEscaped) {
if (nextTok == 't') nextTok = '\t';
if (nextTok == 'b') nextTok = '\b';
if (nextTok == 'n') nextTok = '\n';
if (nextTok == 'r') nextTok = '\r';
if (nextTok == 'f') nextTok = '\f';
}
current.append(nextTok);
lastTokenWasEscaped = false;
}
}
case inDoubleQuote -> {
if (nextTok == '\\') {
lastTokenWasEscaped = true;
} else if (nextTok == '\"' && !lastTokenWasEscaped) {
lastTokenHasBeenQuoted = true;
state = normal;
} else {
if (lastTokenWasEscaped) {
if (nextTok == 't') nextTok = '\t';
if (nextTok == 'b') nextTok = '\b';
if (nextTok == 'n') nextTok = '\n';
if (nextTok == 'r') nextTok = '\r';
if (nextTok == 'f') nextTok = '\f';
}
current.append(nextTok);
lastTokenWasEscaped = false;
}
}
default -> {
switch (nextTok) {
case '\\' -> lastTokenWasEscaped = true;
case '\'' -> state = inQuote;
case '\"' -> state = inDoubleQuote;
case ' ' -> {
if (!lastTokenWasEscaped && (lastTokenHasBeenQuoted || current.length() != 0)) {
result.add(current.toString());
current.setLength(0);
}
}
default -> {
if (lastTokenWasEscaped) {
if (nextTok == 't') nextTok = '\t';
if (nextTok == 'b') nextTok = '\b';
if (nextTok == 'n') nextTok = '\n';
if (nextTok == 'r') nextTok = '\r';
if (nextTok == 'f') nextTok = '\f';
lastTokenWasEscaped = false;
}
current.append(nextTok);
}
}
lastTokenHasBeenQuoted = false;
}
}
current.append(nextTok);
lastTokenWasEscaped = false;
}
}
case inDoubleQuote -> {
if (nextTok == '\\') {
lastTokenWasEscaped = true;
} else if (nextTok == '\"' && !lastTokenWasEscaped) {
lastTokenHasBeenQuoted = true;
state = normal;
} else {
if (lastTokenWasEscaped) {
if (nextTok == 't') nextTok = '\t';
if (nextTok == 'b') nextTok = '\b';
if (nextTok == 'n') nextTok = '\n';
if (nextTok == 'r') nextTok = '\r';
if (nextTok == 'f') nextTok = '\f';
}
current.append(nextTok);
lastTokenWasEscaped = false;
}
if (lastTokenHasBeenQuoted || current.length() != 0) {
result.add(current.toString());
}
default -> {
switch (nextTok) {
case '\\' -> lastTokenWasEscaped = true;
case '\'' -> state = inQuote;
case '\"' -> state = inDoubleQuote;
case ' ' -> {
if (!lastTokenWasEscaped && (lastTokenHasBeenQuoted || current.length() != 0)) {
result.add(current.toString());
current.setLength(0);
}
}
default -> {
if (lastTokenWasEscaped) {
if (nextTok == 't') nextTok = '\t';
if (nextTok == 'b') nextTok = '\b';
if (nextTok == 'n') nextTok = '\n';
if (nextTok == 'r') nextTok = '\r';
if (nextTok == 'f') nextTok = '\f';
lastTokenWasEscaped = false;
}
current.append(nextTok);
}
}
lastTokenHasBeenQuoted = false;
if (state == inQuote || state == inDoubleQuote) {
throw new FirescriptFormatException("unbalanced quotes in " + line);
}
}
return result.toArray(new String[result.size()]);
}
if (lastTokenHasBeenQuoted || current.length() != 0) {
result.add(current.toString());
}
if (state == inQuote || state == inDoubleQuote) {
throw new FirescriptFormatException("unbalanced quotes in " + line);
}
return result.toArray(new String[result.size()]);
}
}

View File

@ -24,51 +24,51 @@ import java.io.IOException;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
public class Rowlf {
JFrame frame = new JFrame();
JPanel frameContainer;
Image logo;
JLabel picLabel;
private JTextField informationText;
private JLabel versionLabel;
private JLabel environmentLabel;
JFrame frame = new JFrame();
JPanel frameContainer;
Image logo;
JLabel picLabel;
private JTextField informationText;
private JLabel versionLabel;
private JLabel environmentLabel;
public Rowlf(JFrame parent) {
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/logo.png")).getScaledInstance(333, 100, Image.SCALE_SMOOTH);
} catch (IOException e) {
System.out.println("ERROR: Failed to open About screen because we couldn't find an image needed to display the page.");
throw new RuntimeException(e);
}
frame.setIconImage(Main.windowIcon);
public Rowlf(JFrame parent) {
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/logo.png")).getScaledInstance(333, 100, Image.SCALE_SMOOTH);
} catch (IOException e) {
System.out.println("ERROR: Failed to open About screen because we couldn't find an image needed to display the page.");
throw new RuntimeException(e);
}
frame.setIconImage(Main.windowIcon);
//frame.add(picLabel);
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
//frame.add(picLabel);
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
informationText.getDocument().putProperty("filterNewlines", Boolean.FALSE);
informationText.setHorizontalAlignment(JTextField.CENTER);
informationText.setText("Created by bonkmaykr, a.k.a. \"Downforce Agent\"\n" +
"\n" +
"Special thanks to:\n" +
"ThatOneBonk, for Thallium and for modding help\n" +
"Wirlaburla, for web hosting and code assistance\n" +
"Psygnosis, for making our favorite game ever\n" +
"and to all the PSVita hackers who made this possible");
informationText.setHighlighter(null);
informationText.getCaret().setVisible(false);
informationText.setFocusable(false);
informationText.getDocument().putProperty("filterNewlines", Boolean.FALSE);
informationText.setHorizontalAlignment(JTextField.CENTER);
informationText.setText("Created by bonkmaykr, a.k.a. \"Downforce Agent\"\n" +
"\n" +
"Special thanks to:\n" +
"ThatOneBonk, for Thallium and for modding help\n" +
"Wirlaburla, for web hosting and code assistance\n" +
"Psygnosis, for making our favorite game ever\n" +
"and to all the PSVita hackers who made this possible");
informationText.setHighlighter(null);
informationText.getCaret().setVisible(false);
informationText.setFocusable(false);
versionLabel.setText("Version " + Main.vstr + " (" + Main.vcode + ")");
environmentLabel.setText("Running on Java " + System.getProperty("java.version") + " for " + System.getProperty("os.name"));
versionLabel.setText("Version " + Main.vstr + " (" + Main.vcode + ")");
environmentLabel.setText("Running on Java " + System.getProperty("java.version") + " for " + System.getProperty("os.name"));
// display window
frame.setSize(400, 320);
frame.setTitle("About Firestar");
frame.setResizable(false);
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(parent);
frame.setVisible(true);
}
// display window
frame.setSize(400, 320);
frame.setTitle("About Firestar");
frame.setResizable(false);
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(parent);
frame.setVisible(true);
}
}

View File

@ -20,57 +20,57 @@ import javax.swing.*;
import java.awt.*;
public class Scooter {
private JFrame frame = new JFrame();
public JProgressBar progressBar;
private JPanel frameContainer;
private JLabel label;
private JFrame frame = new JFrame();
public JProgressBar progressBar;
private JPanel frameContainer;
private JLabel label;
public void showDialog(String title) {
frame.add(frameContainer);
frame.setSize(300, 100);
frame.setTitle(title);
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
frame.setIconImage(Main.windowIcon);
public void showDialog(String title) {
frame.add(frameContainer);
frame.setSize(300, 100);
frame.setTitle(title);
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
frame.setIconImage(Main.windowIcon);
progressBar.setStringPainted(true);
progressBar.setStringPainted(true);
frame.setVisible(true);
}
frame.setVisible(true);
}
public void setProgressMin(int i) {
progressBar.setMinimum(i);
}
public void setProgressMin(int i) {
progressBar.setMinimum(i);
}
public void setProgressValue(int i) {
progressBar.setValue(i);
}
public void setProgressValue(int i) {
progressBar.setValue(i);
}
public void setProgressMax(int i) {
progressBar.setMaximum(i);
}
public void setProgressMax(int i) {
progressBar.setMaximum(i);
}
public int getProgressMin() {
return progressBar.getMinimum();
}
public int getProgressMin() {
return progressBar.getMinimum();
}
public int getProgressValue() {
return progressBar.getValue();
}
public int getProgressValue() {
return progressBar.getValue();
}
public int getProgressMax() {
return progressBar.getMaximum();
}
public int getProgressMax() {
return progressBar.getMaximum();
}
public void setText(String text) {
label.setText(text);
}
public void setText(String text) {
label.setText(text);
}
public void destroyDialog() {
frame.setVisible(false);
frame.dispose();
}
public void destroyDialog() {
frame.setVisible(false);
frame.dispose();
}
}

View File

@ -51,45 +51,45 @@ import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
public class Suggs implements ActionListener, ListSelectionListener {
public JFrame frame = new JFrame();
private JPanel frameContainer;
private JList dSongList;
private JButton moveDownBtn;
private JButton saveBtn;
private JButton cancelBtn;
private JTextField fTitle;
private JTextField fArtist;
private JLabel dTrackNo;
private JLabel dFileSize;
private JButton frontendDemoChooseBtn;
private JButton frontendMainChooseBtn;
private JButton deleteSongBtn;
private JButton addSongBtn;
private JButton moveUpBtn;
private JLabel dSTitle;
private JLabel dMTitle;
private JLabel dSSize;
private JLabel dMSize;
private JCheckBox checkAdditive;
public JFrame frame = new JFrame();
private JPanel frameContainer;
private JList dSongList;
private JButton moveDownBtn;
private JButton saveBtn;
private JButton cancelBtn;
private JTextField fTitle;
private JTextField fArtist;
private JLabel dTrackNo;
private JLabel dFileSize;
private JButton frontendDemoChooseBtn;
private JButton frontendMainChooseBtn;
private JButton deleteSongBtn;
private JButton addSongBtn;
private JButton moveUpBtn;
private JLabel dSTitle;
private JLabel dMTitle;
private JLabel dSSize;
private JLabel dMSize;
private JCheckBox checkAdditive;
private JButton spDeleteBtn;
private JButton mpDeleteBtn;
private JCheckBox checkNormalize;
private Scooter progressDialog;
JFrame parent;
int curIndex = -1;
JFrame parent;
int curIndex = -1;
boolean normalizeVolumes = false;
public class AudioTrack {
public File path; // file name
public String title; // audio title
public String artist; // audio artist
public long size; // file size in bytes
public boolean noConvert;
}
private List<AudioTrack> tracklist = new ArrayList<AudioTrack>();
private File sptrack;
private File mptrack;
public class AudioTrack {
public File path; // file name
public String title; // audio title
public String artist; // audio artist
public long size; // file size in bytes
public boolean noConvert;
}
private List<AudioTrack> tracklist = new ArrayList<AudioTrack>();
private File sptrack;
private File mptrack;
DocumentListener id3TagEditorHandler = new DocumentListener() {
@Override
@ -108,48 +108,48 @@ public class Suggs implements ActionListener, ListSelectionListener {
}
};
public Suggs(JFrame parent) {
public Suggs(JFrame parent) {
this.parent = parent;
parent.setEnabled(false);
parent.setEnabled(false);
frame.setIconImage(Main.windowIcon);
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
frame.setIconImage(Main.windowIcon);
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
frame.setSize(700, 400);
frame.setMinimumSize(new Dimension(700,400));
frame.setTitle("Soundtrack Mod Generator");
frame.setResizable(true);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(parent);
frame.setAlwaysOnTop(true);
frame.setSize(700, 400);
frame.setMinimumSize(new Dimension(700,400));
frame.setTitle("Soundtrack Mod Generator");
frame.setResizable(true);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(parent);
frame.setAlwaysOnTop(true);
cancelBtn.addActionListener(this);
saveBtn.addActionListener(this);
addSongBtn.addActionListener(this); // file picker
deleteSongBtn.addActionListener(this); // delete from list
moveUpBtn.addActionListener(this);
moveDownBtn.addActionListener(this);
fTitle.addActionListener(this); // automatically change selected item when changed &
fArtist.addActionListener(this); // also update field when new item selected
frontendMainChooseBtn.addActionListener(this); // file picker for singleplayer campaign grid music
frontendDemoChooseBtn.addActionListener(this); // file picker for multiplayer lobby music
cancelBtn.addActionListener(this);
saveBtn.addActionListener(this);
addSongBtn.addActionListener(this); // file picker
deleteSongBtn.addActionListener(this); // delete from list
moveUpBtn.addActionListener(this);
moveDownBtn.addActionListener(this);
fTitle.addActionListener(this); // automatically change selected item when changed &
fArtist.addActionListener(this); // also update field when new item selected
frontendMainChooseBtn.addActionListener(this); // file picker for singleplayer campaign grid music
frontendDemoChooseBtn.addActionListener(this); // file picker for multiplayer lobby music
spDeleteBtn.addActionListener(this);
mpDeleteBtn.addActionListener(this);
dSongList.addListSelectionListener(this);
dSongList.addListSelectionListener(this);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
if (!tracklist.isEmpty() || sptrack != null || mptrack != null) {
int result = JOptionPane.showConfirmDialog(frame, "Are you sure?\nAll unsaved changes will be lost.", "Soundtrack Mod Generator", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (result == JOptionPane.NO_OPTION) {return;}
}
parent.setEnabled(true);
e.getWindow().dispose();
}
});
}
});
fTitle.setText("");
fArtist.setText("");
@ -161,53 +161,53 @@ public class Suggs implements ActionListener, ListSelectionListener {
fTitle.getDocument().addDocumentListener(id3TagEditorHandler);
fArtist.getDocument().addDocumentListener(id3TagEditorHandler);
frame.setVisible(true);
}
frame.setVisible(true);
}
private void haveSeggs() { // kill yourself
private void haveSeggs() { // kill yourself
}
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == cancelBtn) {
if (!tracklist.isEmpty() || sptrack != null || mptrack != null) {
int result = JOptionPane.showConfirmDialog(frame, "Are you sure?\nAll unsaved changes will be lost.", "Soundtrack Mod Generator", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (result == JOptionPane.NO_OPTION) {return;}
}
parent.setEnabled(true);
frame.dispose();
} else
if (actionEvent.getSource() == addSongBtn) {addSong();} else
if (actionEvent.getSource() == deleteSongBtn) {remove(curIndex);} else
if (actionEvent.getSource() == moveUpBtn) {moveUp(curIndex);} else
if (actionEvent.getSource() == moveDownBtn) {moveDown(curIndex);} else
if (actionEvent.getSource() == frontendMainChooseBtn) {setSPMusic();} else
if (actionEvent.getSource() == frontendDemoChooseBtn) {setMPMusic();} else
if (actionEvent.getSource() == saveBtn) {
if (tracklist.isEmpty() && sptrack == null && mptrack == null) {
JOptionPane.showMessageDialog(frame, "Please add at least one song to the playlist.", "Error", JOptionPane.ERROR_MESSAGE);
return;
} else {
String deets;
if (tracklist.isEmpty()) {
deets = "no songs";
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == cancelBtn) {
if (!tracklist.isEmpty() || sptrack != null || mptrack != null) {
int result = JOptionPane.showConfirmDialog(frame, "Are you sure?\nAll unsaved changes will be lost.", "Soundtrack Mod Generator", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (result == JOptionPane.NO_OPTION) {return;}
}
parent.setEnabled(true);
frame.dispose();
} else
if (actionEvent.getSource() == addSongBtn) {addSong();} else
if (actionEvent.getSource() == deleteSongBtn) {remove(curIndex);} else
if (actionEvent.getSource() == moveUpBtn) {moveUp(curIndex);} else
if (actionEvent.getSource() == moveDownBtn) {moveDown(curIndex);} else
if (actionEvent.getSource() == frontendMainChooseBtn) {setSPMusic();} else
if (actionEvent.getSource() == frontendDemoChooseBtn) {setMPMusic();} else
if (actionEvent.getSource() == saveBtn) {
if (tracklist.isEmpty() && sptrack == null && mptrack == null) {
JOptionPane.showMessageDialog(frame, "Please add at least one song to the playlist.", "Error", JOptionPane.ERROR_MESSAGE);
return;
} else {
deets = tracklist.size() + " songs";
String deets;
if (tracklist.isEmpty()) {
deets = "no songs";
} else {
deets = tracklist.size() + " songs";
}
if (sptrack != null && mptrack == null) {
deets = deets + " and a custom campaign menu track";
} else if (mptrack != null && sptrack == null) {
deets = deets + " and a custom lobby menu track";
} else if (mptrack != null && sptrack != null) {
deets = deets + ", a custom campaign menu track, and a custom lobby menu track";
}
int result = JOptionPane.showConfirmDialog(frame, "Your custom playlist with " + deets + " will be generated.\nPress YES to continue, or NO to continue editing.", "Soundtrack Mod Generator", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
save();
}
}
if (sptrack != null && mptrack == null) {
deets = deets + " and a custom campaign menu track";
} else if (mptrack != null && sptrack == null) {
deets = deets + " and a custom lobby menu track";
} else if (mptrack != null && sptrack != null) {
deets = deets + ", a custom campaign menu track, and a custom lobby menu track";
}
int result = JOptionPane.showConfirmDialog(frame, "Your custom playlist with " + deets + " will be generated.\nPress YES to continue, or NO to continue editing.", "Soundtrack Mod Generator", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
save();
}
}
} else
} else
if (actionEvent.getSource() == spDeleteBtn) {
dSTitle.setText("no track");
dSSize.setText("no size");
@ -220,40 +220,40 @@ public class Suggs implements ActionListener, ListSelectionListener {
mptrack = null;
mpDeleteBtn.setVisible(false);
}
}
}
@Override
public void valueChanged(ListSelectionEvent listSelectionEvent) {
@Override
public void valueChanged(ListSelectionEvent listSelectionEvent) {
fTitle.getDocument().removeDocumentListener(id3TagEditorHandler);
fArtist.getDocument().removeDocumentListener(id3TagEditorHandler);
curIndex = dSongList.getSelectedIndex();
if (curIndex >= 0) {
fTitle.setEnabled(true);
fArtist.setEnabled(true);
AudioTrack at = tracklist.get(curIndex);
fTitle.setText(at.title);
fArtist.setText(at.artist);
dTrackNo.setText(String.format("MT_%02d", curIndex+1));
dFileSize.setText(at.size + " B");
if (at.size > 1023) {
dFileSize.setText((at.size / 1024) + " KB");
curIndex = dSongList.getSelectedIndex();
if (curIndex >= 0) {
fTitle.setEnabled(true);
fArtist.setEnabled(true);
AudioTrack at = tracklist.get(curIndex);
fTitle.setText(at.title);
fArtist.setText(at.artist);
dTrackNo.setText(String.format("MT_%02d", curIndex+1));
dFileSize.setText(at.size + " B");
if (at.size > 1023) {
dFileSize.setText((at.size / 1024) + " KB");
}
if (at.size > 1048575) {
dFileSize.setText((at.size / 1048576) + " MB");
}
fTitle.getDocument().addDocumentListener(id3TagEditorHandler);
fArtist.getDocument().addDocumentListener(id3TagEditorHandler);
} else {
fTitle.setEnabled(false);
fArtist.setEnabled(false);
fTitle.setText("");
fArtist.setText("");
dTrackNo.setText("\u200E");
dFileSize.setText("\u200E");
fTitle.getDocument().addDocumentListener(id3TagEditorHandler);
fArtist.getDocument().addDocumentListener(id3TagEditorHandler);
}
if (at.size > 1048575) {
dFileSize.setText((at.size / 1048576) + " MB");
}
fTitle.getDocument().addDocumentListener(id3TagEditorHandler);
fArtist.getDocument().addDocumentListener(id3TagEditorHandler);
} else {
fTitle.setEnabled(false);
fArtist.setEnabled(false);
fTitle.setText("");
fArtist.setText("");
dTrackNo.setText("\u200E");
dFileSize.setText("\u200E");
fTitle.getDocument().addDocumentListener(id3TagEditorHandler);
fArtist.getDocument().addDocumentListener(id3TagEditorHandler);
}
}
private void updateSelectionToMatchTextFields() {
tracklist.get(curIndex).title = fTitle.getText();
@ -262,52 +262,56 @@ public class Suggs implements ActionListener, ListSelectionListener {
dSongList.setSelectedIndex(curIndex);
}
private void remove(int index) {
if (index >= 0) {
tracklist.remove(index);
InitializeSongListInGUI();
}
}
private void remove(int index) {
if (index >= 0) {
tracklist.remove(index);
InitializeSongListInGUI();
}
}
private void moveUp(int index) {
if (index > 0) {
Collections.swap(tracklist, index, index - 1);
InitializeSongListInGUI();
}
}
private void moveUp(int index) {
if (index > 0) {
Collections.swap(tracklist, index, index - 1);
InitializeSongListInGUI();
}
}
private void moveDown(int index) {
if (index < (tracklist.size() - 1)) {
Collections.swap(tracklist, index, index + 1);
InitializeSongListInGUI();
}
}
private void moveDown(int index) {
if (index < (tracklist.size() - 1)) {
Collections.swap(tracklist, index, index + 1);
InitializeSongListInGUI();
}
}
private void InitializeSongListInGUI() {
private void InitializeSongListInGUI() {
dSongList.removeListSelectionListener(this); // prevent weird bullshit
dSongList.clearSelection();
dSongList.removeAll();
dSongList.setVisibleRowCount(tracklist.size());
dSongList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
dSongList.clearSelection();
dSongList.removeAll();
dSongList.setVisibleRowCount(tracklist.size());
dSongList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// add text entry for each
int i = 0;
String[] contents = new String[tracklist.size()];
while (i < tracklist.size()) {
// add text entry for each
int i = 0;
String[] contents = new String[tracklist.size()];
while (i < tracklist.size()) {
String dTitleInList; // avoid editing the actual list
String dArtistInList; // otherwise we cause weird JTextField behavior
if (tracklist.get(i).title == null || tracklist.get(i).title.isEmpty())
{dTitleInList = tracklist.get(i).path.getName();} else {dTitleInList = tracklist.get(i).title;}
if (tracklist.get(i).artist == null || tracklist.get(i).artist.isEmpty())
{dArtistInList = "Unknown Artist";} else {dArtistInList = tracklist.get(i).artist;}
contents[i] = dArtistInList + " - " + dTitleInList;
if (tracklist.get(i).title == null || tracklist.get(i).title.isEmpty())
dTitleInList = tracklist.get(i).path.getName();
else
dTitleInList = tracklist.get(i).title;
if (tracklist.get(i).artist == null || tracklist.get(i).artist.isEmpty())
dArtistInList = "Unknown Artist";
else
dArtistInList = tracklist.get(i).artist;
contents[i] = dArtistInList + " - " + dTitleInList;
i++;
}
dSongList.setListData(contents);
i++;
}
dSongList.setListData(contents);
dSongList.setSelectedIndex(curIndex);
dSongList.addListSelectionListener(this);
}
}
private JFileChooser commonSoundFilePicker(boolean multiselect) {
JFileChooser fileChooser = new JFileChooser();
@ -325,13 +329,13 @@ public class Suggs implements ActionListener, ListSelectionListener {
return fileChooser;
}
private void setSPMusic() {
private void setSPMusic() {
JFileChooser fileChooser = commonSoundFilePicker(false);
int result = fileChooser.showOpenDialog(frame);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
sptrack = selectedFile;
dSTitle.setText(selectedFile.getName());
File selectedFile = fileChooser.getSelectedFile();
sptrack = selectedFile;
dSTitle.setText(selectedFile.getName());
dSSize.setText(selectedFile.length() + " B");
if (selectedFile.length() > 1023) {
dSSize.setText((selectedFile.length() / 1024) + " KB");
@ -340,267 +344,267 @@ public class Suggs implements ActionListener, ListSelectionListener {
dSSize.setText((selectedFile.length() / 1048576) + " MB");
}
spDeleteBtn.setVisible(true);
}
}
}
}
private void setMPMusic() {
private void setMPMusic() {
JFileChooser fileChooser = commonSoundFilePicker(false);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
mptrack = selectedFile;
dMTitle.setText(selectedFile.getName());
dMSize.setText(selectedFile.length() + " B");
if (selectedFile.length() > 1023) {
dMSize.setText((selectedFile.length() / 1024) + " KB");
}
if (selectedFile.length() > 1048575) {
dMSize.setText((selectedFile.length() / 1048576) + " MB");
}
mpDeleteBtn.setVisible(true);
}
}
private void addSong() {
JFileChooser fileChooser = commonSoundFilePicker(true);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
File[] selectedFiles = fileChooser.getSelectedFiles();
for (File f : selectedFiles) {
if (f.exists()) {
System.out.println("Importing audio file \"" + f.getName() + "\"");
AudioTrack track = new AudioTrack();
track.path = f;
String fname = f.getName();
if (fname.contains(" - ")) {
track.title = fname.substring(fname.indexOf(" - ")+3, fname.lastIndexOf("."));
track.artist = fname.substring(0, fname.indexOf(" - "));
} else track.title = fname;
track.size = f.length();
tracklist.add(track);
}
}
InitializeSongListInGUI();
}
}
private void save() {
frame.setEnabled(false);
frame.setAlwaysOnTop(false);
normalizeVolumes = checkNormalize.isSelected();
Main.deleteDir(new File(System.getProperty("user.home") + "/.firestar/temp/")); // starts with clean temp
new Thread(() -> {
int progressSize = tracklist.size()+(sptrack != null?1:0)+(mptrack != null?1:0)+1; // Accounting for processes
progressDialog = new Scooter();
progressDialog.showDialog("Soundtrack Mod Generator");
progressDialog.setText("Generating audio files...");
progressDialog.setProgressMax(progressSize);
progressDialog.setProgressValue(0);
progressDialog.progressBar.setStringPainted(false);
try {
new File(Main.inpath + "temp/data/audio/music").mkdirs();
FileOutputStream fos = new FileOutputStream(new File(Main.inpath + "temp/fscript"));
PrintStream ps = new PrintStream(fos);
ps.println("fscript 1");
ps.println("# AUTOGENERATED BY FIRESTAR");
new File(Main.inpath + "temp/ffmpeg/").mkdirs();
for (int i = 0; i < tracklist.size(); i++) {
AudioTrack at = tracklist.get(i);
String trackno = String.format("%02d", i+1);
String oTitle;
if (at.title == null) {oTitle = "";} else {oTitle = at.title;}
String oArtist;
if (at.artist == null) {oArtist = "";} else {oArtist = at.artist;}
new File(Main.inpath + "temp/data/audio/music/" + trackno).mkdirs();
if (at.path.getName().endsWith(".at9")) {
progressDialog.setText("Copying track " + (i+1) + " out of " + tracklist.size() + "...");
try {
// Assume whoever made the AT9s knows what they're doing
System.out.println("Copying track #" + (i+1) + " \"" + at.artist + " - " + at.title + "\"...");
Files.copy(at.path.toPath(), Paths.get(Main.inpath + "temp/data/audio/music/" + trackno + "/music_stereo.at9"), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
mptrack = selectedFile;
dMTitle.setText(selectedFile.getName());
dMSize.setText(selectedFile.length() + " B");
if (selectedFile.length() > 1023) {
dMSize.setText((selectedFile.length() / 1024) + " KB");
}
} else {
progressDialog.setText("Encoding track " + (i+1) + " out of " + tracklist.size() + "...");
try {
System.out.println("Encoding track #" + (i+1) + " \"" + oArtist + " - " + oTitle + "\"...");
if (!at.path.getName().endsWith(".wav") && !at.path.getName().endsWith(".wave")) { // convert to WAV first if it's not readable by at9tool yet
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", at.path.getPath(), "ffmpeg/" + at.path.getName() + ".wav"}, Main.inpath + "temp/");
p.waitFor();
at.path = new File(Main.inpath + "temp/ffmpeg/" + at.path.getName() + ".wav");
if (selectedFile.length() > 1048575) {
dMSize.setText((selectedFile.length() / 1048576) + " MB");
}
mpDeleteBtn.setVisible(true);
}
}
private void addSong() {
JFileChooser fileChooser = commonSoundFilePicker(true);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
File[] selectedFiles = fileChooser.getSelectedFiles();
for (File f : selectedFiles) {
if (f.exists()) {
System.out.println("Importing audio file \"" + f.getName() + "\"");
AudioTrack track = new AudioTrack();
track.path = f;
String fname = f.getName();
if (fname.contains(" - ")) {
track.title = fname.substring(fname.indexOf(" - ")+3, fname.lastIndexOf("."));
track.artist = fname.substring(0, fname.indexOf(" - "));
} else track.title = fname;
track.size = f.length();
tracklist.add(track);
}
if (normalizeVolumes) { // normalize tracks
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", at.path.getPath(), "-filter", "loudnorm=linear=true:i=-5.0:lra=7.0:tp=0.0", /* force sample rate to prevent Random Stupid Bullshit™ */"-ar", "44100", "ffmpeg/" + at.path.getName() + "_normalized.wav"}, Main.inpath + "temp/");
p.waitFor();
at.path = new File(Main.inpath + "temp/ffmpeg/" + at.path.getName() + "_normalized.wav");
}
InitializeSongListInGUI();
}
}
private void save() {
frame.setEnabled(false);
frame.setAlwaysOnTop(false);
normalizeVolumes = checkNormalize.isSelected();
Main.deleteDir(new File(System.getProperty("user.home") + "/.firestar/temp/")); // starts with clean temp
new Thread(() -> {
int progressSize = tracklist.size()+(sptrack != null?1:0)+(mptrack != null?1:0)+1; // Accounting for processes
progressDialog = new Scooter();
progressDialog.showDialog("Soundtrack Mod Generator");
progressDialog.setText("Generating audio files...");
progressDialog.setProgressMax(progressSize);
progressDialog.setProgressValue(0);
progressDialog.progressBar.setStringPainted(false);
try {
new File(Main.inpath + "temp/data/audio/music").mkdirs();
FileOutputStream fos = new FileOutputStream(new File(Main.inpath + "temp/fscript"));
PrintStream ps = new PrintStream(fos);
ps.println("fscript 1");
ps.println("# AUTOGENERATED BY FIRESTAR");
new File(Main.inpath + "temp/ffmpeg/").mkdirs();
for (int i = 0; i < tracklist.size(); i++) {
AudioTrack at = tracklist.get(i);
String trackno = String.format("%02d", i+1);
String oTitle;
if (at.title == null) {oTitle = "";} else {oTitle = at.title;}
String oArtist;
if (at.artist == null) {oArtist = "";} else {oArtist = at.artist;}
new File(Main.inpath + "temp/data/audio/music/" + trackno).mkdirs();
if (at.path.getName().endsWith(".at9")) {
progressDialog.setText("Copying track " + (i+1) + " out of " + tracklist.size() + "...");
try {
// Assume whoever made the AT9s knows what they're doing
System.out.println("Copying track #" + (i+1) + " \"" + at.artist + " - " + at.title + "\"...");
Files.copy(at.path.toPath(), Paths.get(Main.inpath + "temp/data/audio/music/" + trackno + "/music_stereo.at9"), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
Process p = Main.exec(new String[]{Main.inpath + "at9tool.exe", "-e", "-br", "144", at.path.getPath(), "data/audio/music/" + trackno + "/music_stereo.at9"}, Main.inpath + "temp/");
p.waitFor();
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
}
String ocmd = "modify";
if (i >= 12) ocmd = "create";
String oArtistLine;
if (!oArtist.isEmpty()) {
oArtistLine = oArtist.replace("\"", "\\\"")+"\\n";
} else {
oArtistLine = "";
}
int i2 = 0;
while (i2 < 15 /*17 languages*/) {
String language = "INTERNAL_ERROR";
switch (i2) {
case 0 -> language = "american";
case 1 -> language = "danish";
case 2 -> language = "dutch";
case 3 -> language = "english";
case 4 -> language = "finnish";
case 5 -> language = "french";
case 6 -> language = "german";
case 7 -> language = "italian";
case 8 -> language = "japanese";
case 9 -> language = "norwegian";
case 10 -> language = "polish";
case 11 -> language = "portuguese";
case 12 -> language = "russian";
case 13 -> language = "spanish";
case 14 -> language = "swedish";
default -> {
int result = JOptionPane.showConfirmDialog(frame, "Firestar encountered an internal error.\nString 'language' exported to FSCRIPT was blank.", "Fatal Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE);
if (result == JOptionPane.OK_OPTION) {System.exit(1);} //user safety
} else {
progressDialog.setText("Encoding track " + (i+1) + " out of " + tracklist.size() + "...");
try {
System.out.println("Encoding track #" + (i+1) + " \"" + oArtist + " - " + oTitle + "\"...");
if (!at.path.getName().endsWith(".wav") && !at.path.getName().endsWith(".wave")) { // convert to WAV first if it's not readable by at9tool yet
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", at.path.getPath(), "ffmpeg/" + at.path.getName() + ".wav"}, Main.inpath + "temp/");
p.waitFor();
at.path = new File(Main.inpath + "temp/ffmpeg/" + at.path.getName() + ".wav");
}
if (normalizeVolumes) { // normalize tracks
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", at.path.getPath(), "-filter", "loudnorm=linear=true:i=-5.0:lra=7.0:tp=0.0", /* force sample rate to prevent Random Stupid Bullshit™ */"-ar", "44100", "ffmpeg/" + at.path.getName() + "_normalized.wav"}, Main.inpath + "temp/");
p.waitFor();
at.path = new File(Main.inpath + "temp/ffmpeg/" + at.path.getName() + "_normalized.wav");
}
Process p = Main.exec(new String[]{Main.inpath + "at9tool.exe", "-e", "-br", "144", at.path.getPath(), "data/audio/music/" + trackno + "/music_stereo.at9"}, Main.inpath + "temp/");
p.waitFor();
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
//case 9: language = "korean"; break;
//case 16: language = "traditionalchinese"; break;
ps.println("file \"data/plugins/languages/"+language+"/entries.xml\" xml "+ocmd+" StringTable.entry#MT_"+trackno+" set attribute \"string\" \""+oArtistLine+oTitle.replace("\"", "\\\"")+"\"");
i2++;
}
String ocmd = "modify";
if (i >= 12) ocmd = "create";
String oArtistLine;
if (!oArtist.isEmpty()) {
oArtistLine = oArtist.replace("\"", "\\\"")+"\\n";
} else {
oArtistLine = "";
}
int i2 = 0;
while (i2 < 15 /*17 languages*/) {
String language = "INTERNAL_ERROR";
switch (i2) {
case 0 -> language = "american";
case 1 -> language = "danish";
case 2 -> language = "dutch";
case 3 -> language = "english";
case 4 -> language = "finnish";
case 5 -> language = "french";
case 6 -> language = "german";
case 7 -> language = "italian";
case 8 -> language = "japanese";
case 9 -> language = "norwegian";
case 10 -> language = "polish";
case 11 -> language = "portuguese";
case 12 -> language = "russian";
case 13 -> language = "spanish";
case 14 -> language = "swedish";
default -> {
int result = JOptionPane.showConfirmDialog(frame, "Firestar encountered an internal error.\nString 'language' exported to FSCRIPT was blank.", "Fatal Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE);
if (result == JOptionPane.OK_OPTION) {System.exit(1);} //user safety
}
}
//case 9: language = "korean"; break;
//case 16: language = "traditionalchinese"; break;
ps.println("file \"data/plugins/languages/"+language+"/entries.xml\" xml "+ocmd+" StringTable.entry#MT_"+trackno+" set attribute \"string\" \""+oArtistLine+oTitle.replace("\"", "\\\"")+"\"");
i2++;
}
ps.println("file \"data/audio/music/"+trackno+"/music_stereo.fft\" delete");
progressDialog.setProgressValue(i+1);
}
ps.println("file \"data/audio/music/"+trackno+"/music_stereo.fft\" delete");
progressDialog.setProgressValue(i+1);
}
for (int s = tracklist.size(); s < 12; s++) {
ps.println("file \"data/audio/music/"+String.format("%02d", s+1)+"/music_stereo.fft\" delete");
}
if (sptrack != null) {
progressDialog.setText("Encoding singleplayer frontend track...");
if (sptrack.exists()) {
for (int s = tracklist.size(); s < 12; s++) {
ps.println("file \"data/audio/music/"+String.format("%02d", s+1)+"/music_stereo.fft\" delete");
}
if (sptrack != null) {
progressDialog.setText("Encoding singleplayer frontend track...");
if (sptrack.exists()) {
try {
System.out.println("Encoding singleplayer frontend track...");
if (!sptrack.getName().endsWith(".wav") && !sptrack.getName().endsWith(".wave")) { // convert to WAV first if it's not readable by at9tool yet
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", sptrack.getPath(), "ffmpeg/" + sptrack.getName() + ".wav"}, Main.inpath + "temp/");
p.waitFor();
sptrack = new File(Main.inpath + "temp/ffmpeg/" + sptrack.getName() + ".wav");
}
if (normalizeVolumes) { // normalize tracks
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", sptrack.getPath(), "-filter", "loudnorm=linear=true:i=-10.0:lra=12.0:tp=-2.0", /* force sample rate to prevent Random Stupid Bullshit™ */"-ar", "44100", "ffmpeg/" + sptrack.getName() + "_normalized.wav"}, Main.inpath + "temp/");
p.waitFor();
sptrack = new File(Main.inpath + "temp/ffmpeg/" + sptrack.getName() + "_normalized.wav");
}
new File(Main.inpath + "temp/data/audio/music/FEMusic").mkdirs();
Process p = Main.exec(new String[]{Main.inpath + "at9tool.exe", "-e", "-br", "144", sptrack.getPath(), "data/audio/music/FEMusic/frontend_stereo.at9"}, System.getProperty("user.home") + "/.firestar/temp/");
p.waitFor();
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
}
ps.println("file \"data/audio/music/FEMusic/frontend_stereo.fft\" delete");
progressDialog.setProgressValue(progressDialog.getProgressValue()+1);
}
if (mptrack != null) {
progressDialog.setText("Encoding multiplayer frontend track...");
try {
assert(mptrack.exists());
System.out.println("Encoding multiplayer frontend track...");
if (!mptrack.getName().endsWith(".wav") && !mptrack.getName().endsWith(".wave")) { // convert to WAV first if it's not readable by at9tool yet
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", mptrack.getPath(), "ffmpeg/" + mptrack.getName() + ".wav"}, Main.inpath + "temp/");
p.waitFor();
mptrack = new File(Main.inpath + "temp/ffmpeg/" + mptrack.getName() + ".wav");
}
if (normalizeVolumes) { // normalize tracks
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", mptrack.getPath(), "-filter", "loudnorm=linear=true:i=-10.0:lra=12.0:tp=-2.0", /* force sample rate to prevent Random Stupid Bullshit™ */"-ar", "44100", "ffmpeg/" + mptrack.getName() + "_normalized.wav"}, Main.inpath + "temp/");
p.waitFor();
mptrack = new File(Main.inpath + "temp/ffmpeg/" + mptrack.getName() + "_normalized.wav");
}
new File(Main.inpath + "temp/data/audio/music/FEDemoMusic").mkdirs();
Process p = Main.exec(new String[]{Main.inpath + "at9tool.exe", "-e", "-br", "144", mptrack.getPath(), "data/audio/music/FEDemoMusic/frontend_stereo.at9"}, System.getProperty("user.home") + "/.firestar/temp/");
p.waitFor();
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
ps.println("file \"data/audio/music/FEDemoMusic/frontend_stereo.fft\" delete");
progressDialog.setProgressValue(progressDialog.getProgressValue()+1);
}
System.out.println("Finished encoding.");
progressDialog.setText("Generating Music Definitions...");
try {
System.out.println("Encoding singleplayer frontend track...");
if (!sptrack.getName().endsWith(".wav") && !sptrack.getName().endsWith(".wave")) { // convert to WAV first if it's not readable by at9tool yet
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", sptrack.getPath(), "ffmpeg/" + sptrack.getName() + ".wav"}, Main.inpath + "temp/");
p.waitFor();
sptrack = new File(Main.inpath + "temp/ffmpeg/" + sptrack.getName() + ".wav");
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document defDoc = docBuilder.newDocument();
Element docScreen = defDoc.createElement("Screen");
docScreen.setAttribute("name", "Top");
for (int i = 0; i < tracklist.size(); i++) { // TODO: support for additive
AudioTrack at = tracklist.get(i);
String trackno = String.format("%02d", i+1);
Element trackElem = defDoc.createElement("PI_Music");
trackElem.setAttribute("name", trackno);
Element pathElem = defDoc.createElement("Values");
pathElem.setAttribute("location", "data\\audio\\music\\"+trackno);
trackElem.appendChild(pathElem);
Element artistElem = defDoc.createElement("Entry");
artistElem.setAttribute("Artist", at.artist);
trackElem.appendChild(artistElem);
Element titleElem = defDoc.createElement("Entry");
titleElem.setAttribute("Label", at.title);
trackElem.appendChild(titleElem);
docScreen.appendChild(trackElem);
System.out.println("Adding \"" + trackno + ". " + at.artist + " - " + at.title + "\" to Definition.xml");
}
if (normalizeVolumes) { // normalize tracks
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", sptrack.getPath(), "-filter", "loudnorm=linear=true:i=-10.0:lra=12.0:tp=-2.0", /* force sample rate to prevent Random Stupid Bullshit™ */"-ar", "44100", "ffmpeg/" + sptrack.getName() + "_normalized.wav"}, Main.inpath + "temp/");
p.waitFor();
sptrack = new File(Main.inpath + "temp/ffmpeg/" + sptrack.getName() + "_normalized.wav");
}
new File(Main.inpath + "temp/data/audio/music/FEMusic").mkdirs();
Process p = Main.exec(new String[]{Main.inpath + "at9tool.exe", "-e", "-br", "144", sptrack.getPath(), "data/audio/music/FEMusic/frontend_stereo.at9"}, System.getProperty("user.home") + "/.firestar/temp/");
p.waitFor();
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
defDoc.appendChild(docScreen);
new File(Main.inpath + "temp/data/plugins/music/").mkdirs();
FileOutputStream output = new FileOutputStream(Main.inpath + "temp/data/plugins/music/Definition.xml");
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(defDoc);
StreamResult result = new StreamResult(output);
transformer.transform(source, result);
} catch (IOException | ParserConfigurationException | TransformerException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
}
ps.println("file \"data/audio/music/FEMusic/frontend_stereo.fft\" delete");
progressDialog.setProgressValue(progressDialog.getProgressValue()+1);
}
if (mptrack != null) {
progressDialog.setText("Encoding multiplayer frontend track...");
try {
assert(mptrack.exists());
System.out.println("Encoding multiplayer frontend track...");
if (!mptrack.getName().endsWith(".wav") && !mptrack.getName().endsWith(".wave")) { // convert to WAV first if it's not readable by at9tool yet
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", mptrack.getPath(), "ffmpeg/" + mptrack.getName() + ".wav"}, Main.inpath + "temp/");
p.waitFor();
mptrack = new File(Main.inpath + "temp/ffmpeg/" + mptrack.getName() + ".wav");
}
if (normalizeVolumes) { // normalize tracks
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", mptrack.getPath(), "-filter", "loudnorm=linear=true:i=-10.0:lra=12.0:tp=-2.0", /* force sample rate to prevent Random Stupid Bullshit™ */"-ar", "44100", "ffmpeg/" + mptrack.getName() + "_normalized.wav"}, Main.inpath + "temp/");
p.waitFor();
mptrack = new File(Main.inpath + "temp/ffmpeg/" + mptrack.getName() + "_normalized.wav");
}
new File(Main.inpath + "temp/data/audio/music/FEDemoMusic").mkdirs();
Process p = Main.exec(new String[]{Main.inpath + "at9tool.exe", "-e", "-br", "144", mptrack.getPath(), "data/audio/music/FEDemoMusic/frontend_stereo.at9"}, System.getProperty("user.home") + "/.firestar/temp/");
p.waitFor();
} catch (IOException | InterruptedException ex) {
progressDialog.setProgressValue(progressDialog.getProgressValue()+1);
progressDialog.setText("Finalizing script...");
System.out.println("Finalizing Fscript...");
ps.println("# END FIRESTAR AUTOGENERATION");
ps.close();
fos.close();
} catch (IOException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
ps.println("file \"data/audio/music/FEDemoMusic/frontend_stereo.fft\" delete");
progressDialog.setProgressValue(progressDialog.getProgressValue()+1);
}
System.out.println("Finished encoding.");
}
progressDialog.setText("Generating Music Definitions...");
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
progressDialog.setProgressValue(progressDialog.getProgressValue()+1);
Document defDoc = docBuilder.newDocument();
Element docScreen = defDoc.createElement("Screen");
docScreen.setAttribute("name", "Top");
for (int i = 0; i < tracklist.size(); i++) { // TODO: support for additive
AudioTrack at = tracklist.get(i);
String trackno = String.format("%02d", i+1);
Element trackElem = defDoc.createElement("PI_Music");
trackElem.setAttribute("name", trackno);
Element pathElem = defDoc.createElement("Values");
pathElem.setAttribute("location", "data\\audio\\music\\"+trackno);
trackElem.appendChild(pathElem);
Element artistElem = defDoc.createElement("Entry");
artistElem.setAttribute("Artist", at.artist);
trackElem.appendChild(artistElem);
Element titleElem = defDoc.createElement("Entry");
titleElem.setAttribute("Label", at.title);
trackElem.appendChild(titleElem);
docScreen.appendChild(trackElem);
System.out.println("Adding \"" + trackno + ". " + at.artist + " - " + at.title + "\" to Definition.xml");
}
defDoc.appendChild(docScreen);
new File(Main.inpath + "temp/data/plugins/music/").mkdirs();
FileOutputStream output = new FileOutputStream(Main.inpath + "temp/data/plugins/music/Definition.xml");
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(defDoc);
StreamResult result = new StreamResult(output);
transformer.transform(source, result);
} catch (IOException | ParserConfigurationException | TransformerException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
progressDialog.setProgressValue(progressDialog.getProgressValue()+1);
progressDialog.setText("Finalizing script...");
System.out.println("Finalizing Fscript...");
ps.println("# END FIRESTAR AUTOGENERATION");
ps.close();
fos.close();
} catch (IOException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
progressDialog.setProgressValue(progressDialog.getProgressValue()+1);
progressDialog.destroyDialog();
frame.dispose();
Main.deleteDir(new File(Main.inpath + "temp/ffmpeg/"));
Clifford saveDialog = new Clifford();
saveDialog.isSoundtrack = true;
saveDialog.Action(frame, new File(Main.inpath + "temp/"));
parent.setEnabled(true);
}).start();
}
progressDialog.destroyDialog();
frame.dispose();
Main.deleteDir(new File(Main.inpath + "temp/ffmpeg/"));
Clifford saveDialog = new Clifford();
saveDialog.isSoundtrack = true;
saveDialog.Action(frame, new File(Main.inpath + "temp/"));
parent.setEnabled(true);
}).start();
}
}

View File

@ -28,128 +28,128 @@ import java.io.IOException;
import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE;
public class Waldorf implements ActionListener {
private JFrame frame = new JFrame();
private JPanel frameContainer;
private JButton okbtn;
private JButton cancelbtn;
private JLabel fOutpath;
private JButton resetbtn;
private JButton bOpenFolder;
private JButton dwnSDKbtn;
private JButton dwnARCbtn;
private JButton fOutpathChangebtn;
private JCheckBox checkUpdatesToggle;
private JButton bDelArcs;
private JFrame frame = new JFrame();
private JPanel frameContainer;
private JButton okbtn;
private JButton cancelbtn;
private JLabel fOutpath;
private JButton resetbtn;
private JButton bOpenFolder;
private JButton dwnSDKbtn;
private JButton dwnARCbtn;
private JButton fOutpathChangebtn;
private JCheckBox checkUpdatesToggle;
private JButton bDelArcs;
MissPiggy invoker;
private String tOutPath = Main.outpath;
MissPiggy invoker;
private String tOutPath = Main.outpath;
public void Action(MissPiggy inv) {
invoker = inv;
public void Action(MissPiggy inv) {
invoker = inv;
frame.add(frameContainer);
frame.setIconImage(Main.windowIcon);
frame.setSize(600, 300); // 1280 800
frame.setMinimumSize(new Dimension(200,100));
frame.setTitle("Options");
frame.setResizable(false);
frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(inv.frame);
frame.setAlwaysOnTop(true);
frame.add(frameContainer);
frame.setIconImage(Main.windowIcon);
frame.setSize(600, 300); // 1280 800
frame.setMinimumSize(new Dimension(200,100));
frame.setTitle("Options");
frame.setResizable(false);
frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(inv.frame);
frame.setAlwaysOnTop(true);
cancelbtn.addActionListener(this);
okbtn.addActionListener(this);
resetbtn.addActionListener(this);
bOpenFolder.addActionListener(this);
bDelArcs.addActionListener(this);
dwnARCbtn.addActionListener(this);
dwnSDKbtn.addActionListener(this);
fOutpathChangebtn.addActionListener(this);
cancelbtn.addActionListener(this);
okbtn.addActionListener(this);
resetbtn.addActionListener(this);
bOpenFolder.addActionListener(this);
bDelArcs.addActionListener(this);
dwnARCbtn.addActionListener(this);
dwnSDKbtn.addActionListener(this);
fOutpathChangebtn.addActionListener(this);
fOutpath.setText(Main.outpath);
checkUpdatesToggle.setSelected(Main.checkUpdates);
fOutpath.setText(Main.outpath);
checkUpdatesToggle.setSelected(Main.checkUpdates);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
invoker.frame.setEnabled(true);
e.getWindow().dispose();
}
});
}
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
invoker.frame.setEnabled(true);
e.getWindow().dispose();
}
});
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == cancelbtn) {
invoker.frame.setEnabled(true);
frame.dispose();
} else
if (actionEvent.getSource() == okbtn) {
Main.outpath = tOutPath;
Main.checkUpdates = checkUpdatesToggle.isSelected();
Main.writeConf();
Main.loadConf();
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == cancelbtn) {
invoker.frame.setEnabled(true);
frame.dispose();
} else
if (actionEvent.getSource() == okbtn) {
Main.outpath = tOutPath;
Main.checkUpdates = checkUpdatesToggle.isSelected();
Main.writeConf();
Main.loadConf();
invoker.frame.setEnabled(true);
frame.dispose();
} else
if (actionEvent.getSource() == resetbtn) {
int result = JOptionPane.showConfirmDialog(frame,"Are you sure you want to redo the initial setup?", "Restore Default Settings", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
System.out.println("Restoring default settings");
new File(System.getProperty("user.home") + "/.firestar/firestar.conf").delete();
int result2 = JOptionPane.showConfirmDialog(frame,"Firestar will now close.", "Restore Default Settings", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE);
if (result2 == JOptionPane.OK_OPTION) {
System.exit(0);
}
}
} else
if (actionEvent.getSource() == bOpenFolder) {
try {
Desktop.getDesktop().open(new File(Main.inpath));
} catch (IOException e) {
throw new RuntimeException(e);
}
} else
if (actionEvent.getSource() == bDelArcs) {
int result = JOptionPane.showConfirmDialog(frame, "All existing PSARC dumps will be deleted.\nDo you want to continue?", "Delete PSARCs", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (result == JOptionPane.NO_OPTION) {return;}
System.out.println("User requested arc wipe, deleting existing PSARCs");
new File(Main.inpath + "data.psarc").delete();
new File(Main.inpath + "data1.psarc").delete();
new File(Main.inpath + "data2.psarc").delete();
new File(Main.inpath + "dlc1.psarc").delete();
new File(Main.inpath + "dlc2.psarc").delete();
JOptionPane.showMessageDialog(frame, "PSARC files purged.", "Delete PSARCs", JOptionPane.INFORMATION_MESSAGE);
} else
if (actionEvent.getSource() == dwnARCbtn) {
new Bert(invoker.frame);
frame.dispose();
} else
if (actionEvent.getSource() == dwnSDKbtn) {
Thread downloaderPopupThread = new Thread(new Runnable() {
@Override
public void run() {
Main.downloadDependenciesBeforeSetVisible(invoker.frame);
invoker.frame.setEnabled(true);
}
});
downloaderPopupThread.start();
frame.dispose();
} else
if (actionEvent.getSource() == fOutpathChangebtn) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
if (fileChooser.getSelectedFile().isDirectory()) {
tOutPath = fileChooser.getSelectedFile().getAbsolutePath()+"/";
fOutpath.setText(tOutPath);
}
}
}
}
invoker.frame.setEnabled(true);
frame.dispose();
} else
if (actionEvent.getSource() == resetbtn) {
int result = JOptionPane.showConfirmDialog(frame,"Are you sure you want to redo the initial setup?", "Restore Default Settings", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
System.out.println("Restoring default settings");
new File(System.getProperty("user.home") + "/.firestar/firestar.conf").delete();
int result2 = JOptionPane.showConfirmDialog(frame,"Firestar will now close.", "Restore Default Settings", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE);
if (result2 == JOptionPane.OK_OPTION) {
System.exit(0);
}
}
} else
if (actionEvent.getSource() == bOpenFolder) {
try {
Desktop.getDesktop().open(new File(Main.inpath));
} catch (IOException e) {
throw new RuntimeException(e);
}
} else
if (actionEvent.getSource() == bDelArcs) {
int result = JOptionPane.showConfirmDialog(frame, "All existing PSARC dumps will be deleted.\nDo you want to continue?", "Delete PSARCs", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (result == JOptionPane.NO_OPTION) {return;}
System.out.println("User requested arc wipe, deleting existing PSARCs");
new File(Main.inpath + "data.psarc").delete();
new File(Main.inpath + "data1.psarc").delete();
new File(Main.inpath + "data2.psarc").delete();
new File(Main.inpath + "dlc1.psarc").delete();
new File(Main.inpath + "dlc2.psarc").delete();
JOptionPane.showMessageDialog(frame, "PSARC files purged.", "Delete PSARCs", JOptionPane.INFORMATION_MESSAGE);
} else
if (actionEvent.getSource() == dwnARCbtn) {
new Bert(invoker.frame);
frame.dispose();
} else
if (actionEvent.getSource() == dwnSDKbtn) {
Thread downloaderPopupThread = new Thread(new Runnable() {
@Override
public void run() {
Main.downloadDependenciesBeforeSetVisible(invoker.frame);
invoker.frame.setEnabled(true);
}
});
downloaderPopupThread.start();
frame.dispose();
} else
if (actionEvent.getSource() == fOutpathChangebtn) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
if (fileChooser.getSelectedFile().isDirectory()) {
tOutPath = fileChooser.getSelectedFile().getAbsolutePath()+"/";
fOutpath.setText(tOutPath);
}
}
}
}
}

View File

@ -31,176 +31,176 @@ import java.nio.file.Files;
import static javax.swing.WindowConstants.EXIT_ON_CLOSE;
public class WilkinsCoffee implements ActionListener {
Image logo;
public Pages page;
public JFrame frame = new JFrame();
private JPanel frameContainer;
private JLabel picLabel;
private JEditorPane instructions;
private JButton contBtn;
private JPanel inputContainer;
private JButton PSARC_downBtn;
private JButton PSARC_impBtn;
private JPanel inputContainer2;
private JButton EXPORT_openFolderBtn;
private JLabel pathDisplay;
private JPanel checklistContainer;
private JLabel checklistFury;
private JLabel checklistHD;
private JLabel checklistPatch2;
private JLabel checklistPatch1;
private JLabel checklistBase;
Image logo;
public Pages page;
public JFrame frame = new JFrame();
private JPanel frameContainer;
private JLabel picLabel;
private JEditorPane instructions;
private JButton contBtn;
private JPanel inputContainer;
private JButton PSARC_downBtn;
private JButton PSARC_impBtn;
private JPanel inputContainer2;
private JButton EXPORT_openFolderBtn;
private JLabel pathDisplay;
private JPanel checklistContainer;
private JLabel checklistFury;
private JLabel checklistHD;
private JLabel checklistPatch2;
private JLabel checklistPatch1;
private JLabel checklistBase;
public enum Pages {
INTRO(0),
PSARC(1),
EXPORT_LOCATION(2),
DONE(3);
public enum Pages {
INTRO(0),
PSARC(1),
EXPORT_LOCATION(2),
DONE(3);
public final int value;
public final int value;
private Pages(int i) {
this.value = i;
}
}
private Pages(int i) {
this.value = i;
}
}
private String outPathTemp = System.getProperty("user.home") + "/Documents/";
private boolean sdkInstalled = false;
private String outPathTemp = System.getProperty("user.home") + "/Documents/";
private boolean sdkInstalled = false;
public void setup() {
page = Pages.INTRO;
inputContainer.setVisible(false);
checklistContainer.setVisible(false);
inputContainer2.setVisible(false);
public void setup() {
page = Pages.INTRO;
inputContainer.setVisible(false);
checklistContainer.setVisible(false);
inputContainer2.setVisible(false);
// check if this is windows or not
if(System.getProperty("os.name").contains("Windows")) {Main.windows = true;System.out.println("Assuming we should NOT use WINE based on known system variables.");}
else {Main.windows = false;System.out.println("Assuming we should use WINE based on known system variables.");}
// check if this is windows or not
if(System.getProperty("os.name").contains("Windows")) {Main.windows = true;System.out.println("Assuming we should NOT use WINE based on known system variables.");}
else {Main.windows = false;System.out.println("Assuming we should use WINE based on known system variables.");}
// reformat path slightly for windows
if (Main.windows) {outPathTemp.replace("/", "\\");}
// reformat path slightly for windows
if (Main.windows) {outPathTemp.replace("/", "\\");}
frame.setIconImage(Main.windowIcon);
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/programIcon.png")).getScaledInstance(96, 96, Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
} catch (IOException e) {
System.out.println("ERROR: Missing resource in Wilkins. Page will be without images.");
picLabel.setText("");
}
frame.setIconImage(Main.windowIcon);
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/programIcon.png")).getScaledInstance(96, 96, Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
} catch (IOException e) {
System.out.println("ERROR: Missing resource in Wilkins. Page will be without images.");
picLabel.setText("");
}
String bodyRule = "html, body {margin:0px;} p#first-p {margin-top:-13px;} p {margin-left:-20px;}";
((HTMLDocument)instructions.getDocument()).getStyleSheet().addRule(bodyRule);
instructions.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE); // makes text smaller than joe biden's windmill if font set manually. wtf??
contBtn.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
PSARC_downBtn.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
PSARC_impBtn.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
EXPORT_openFolderBtn.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
String bodyRule = "html, body {margin:0px;} p#first-p {margin-top:-13px;} p {margin-left:-20px;}";
((HTMLDocument)instructions.getDocument()).getStyleSheet().addRule(bodyRule);
instructions.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE); // makes text smaller than joe biden's windmill if font set manually. wtf??
contBtn.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
PSARC_downBtn.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
PSARC_impBtn.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
EXPORT_openFolderBtn.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
contBtn.addActionListener(this);
PSARC_downBtn.addActionListener(this);
PSARC_impBtn.addActionListener(this);
EXPORT_openFolderBtn.addActionListener(this);
contBtn.addActionListener(this);
PSARC_downBtn.addActionListener(this);
PSARC_impBtn.addActionListener(this);
EXPORT_openFolderBtn.addActionListener(this);
frame.setSize(400, 400);
frame.setTitle("Firestar Setup");
frame.setResizable(false);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
frame.setSize(400, 400);
frame.setTitle("Firestar Setup");
frame.setResizable(false);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
WilkinsCoffee threadParent = this;
if (actionEvent.getSource() == PSARC_downBtn) {
Thread waiterThread = new Thread(new Runnable() {@Override
public void run() {
if (new Bert(frame).reportWhenDownloaded(threadParent)) {
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
@Override
public void actionPerformed(ActionEvent actionEvent) {
WilkinsCoffee threadParent = this;
if (actionEvent.getSource() == PSARC_downBtn) {
Thread waiterThread = new Thread(new Runnable() {@Override
public void run() {
if (new Bert(frame).reportWhenDownloaded(threadParent)) {
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
refreshChecklist();
}
}});
waiterThread.start();
} else
if (actionEvent.getSource() == PSARC_impBtn) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
FileFilter fileChooserFilter = new FileNameExtensionFilter("Sony Playstation Archive File", "psarc");
fileChooser.setFileFilter(fileChooserFilter);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
try {
Files.copy(fileChooser.getSelectedFile().toPath(), new File(Main.inpath + fileChooser.getSelectedFile().getName()).toPath());
refreshChecklist();
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} catch (IOException e) {
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(frame, "An error has occured.\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
} else
if (actionEvent.getSource() == EXPORT_openFolderBtn) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
if (fileChooser.getSelectedFile().isDirectory()) {
outPathTemp = fileChooser.getSelectedFile().getAbsolutePath()+"/";
pathDisplay.setText("Export path: " + outPathTemp);
}
}
} else
if (actionEvent.getSource() == contBtn) {
switch (page) {
case INTRO:
if (!new File(Main.inpath + "psp2psarc.exe").exists()) { // we may have been here before // nag
frame.setEnabled(false);
int result = JOptionPane.showConfirmDialog(frame, "Firestar needs to download additional software to function. Setup is automatic and will only take a few minutes.\nIf you select NO, you will have to download additional dependencies later on.\n\nContinue?", "Firestar Setup", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
sdkInstalled = true;
Thread downloaderPopupThread = new Thread(new Runnable() {
@Override
public void run() {
Main.downloadDependenciesBeforeSetVisible(frame);
frame.setEnabled(true);
}
});
downloaderPopupThread.start();
} else {
frame.setEnabled(true);
}
} else {
sdkInstalled = true;
}
refreshChecklist();
}
}});
waiterThread.start();
} else
if (actionEvent.getSource() == PSARC_impBtn) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
FileFilter fileChooserFilter = new FileNameExtensionFilter("Sony Playstation Archive File", "psarc");
fileChooser.setFileFilter(fileChooserFilter);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
try {
Files.copy(fileChooser.getSelectedFile().toPath(), new File(Main.inpath + fileChooser.getSelectedFile().getName()).toPath());
refreshChecklist();
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} catch (IOException e) {
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(frame, "An error has occured.\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
} else
if (actionEvent.getSource() == EXPORT_openFolderBtn) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
if (fileChooser.getSelectedFile().isDirectory()) {
outPathTemp = fileChooser.getSelectedFile().getAbsolutePath()+"/";
pathDisplay.setText("Export path: " + outPathTemp);
}
}
} else
if (actionEvent.getSource() == contBtn) {
switch (page) {
case INTRO:
if (!new File(Main.inpath + "psp2psarc.exe").exists()) { // we may have been here before // nag
frame.setEnabled(false);
int result = JOptionPane.showConfirmDialog(frame, "Firestar needs to download additional software to function. Setup is automatic and will only take a few minutes.\nIf you select NO, you will have to download additional dependencies later on.\n\nContinue?", "Firestar Setup", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
sdkInstalled = true;
Thread downloaderPopupThread = new Thread(new Runnable() {
@Override
public void run() {
Main.downloadDependenciesBeforeSetVisible(frame);
frame.setEnabled(true);
}
});
downloaderPopupThread.start();
} else {
frame.setEnabled(true);
}
} else {
sdkInstalled = true;
}
page = Pages.PSARC;
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/setupIconPSARC.png")).getScaledInstance(96, 96, Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
} catch (IOException e) {
System.out.println("ERROR: Missing resource in Wilkins. Page will be without images.");
picLabel.setText("");
}
page = Pages.PSARC;
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/setupIconPSARC.png")).getScaledInstance(96, 96, Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
} catch (IOException e) {
System.out.println("ERROR: Missing resource in Wilkins. Page will be without images.");
picLabel.setText("");
}
contBtn.setEnabled(false);
contBtn.setBackground(new Color(102, 74, 58)); //brown
refreshChecklist();
inputContainer.setVisible(true);
checklistContainer.setVisible(true);
if (!sdkInstalled) {
PSARC_downBtn.setEnabled(false);
PSARC_downBtn.setBackground(new Color(102, 74, 58)); //brown
}
contBtn.setEnabled(false);
contBtn.setBackground(new Color(102, 74, 58)); //brown
refreshChecklist();
inputContainer.setVisible(true);
checklistContainer.setVisible(true);
if (!sdkInstalled) {
PSARC_downBtn.setEnabled(false);
PSARC_downBtn.setBackground(new Color(102, 74, 58)); //brown
}
instructions.setText("<html>\n" +
" <head>\n" +
instructions.setText("<html>\n" +
" <head>\n" +
" \n" +
" </head>\n" +
" <body>\n" +
@ -213,24 +213,24 @@ public class WilkinsCoffee implements ActionListener {
" </body>\n" +
"</html>\n");
break;
case PSARC:
page = Pages.EXPORT_LOCATION;
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/setupIconEXPORT.png")).getScaledInstance(96, 96, Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
} catch (IOException e) {
System.out.println("ERROR: Missing resource in Wilkins. Page will be without images.");
picLabel.setText("");
}
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
inputContainer.setVisible(false);
checklistContainer.setVisible(false);
inputContainer2.setVisible(true);
break;
case PSARC:
page = Pages.EXPORT_LOCATION;
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/setupIconEXPORT.png")).getScaledInstance(96, 96, Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
} catch (IOException e) {
System.out.println("ERROR: Missing resource in Wilkins. Page will be without images.");
picLabel.setText("");
}
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
inputContainer.setVisible(false);
checklistContainer.setVisible(false);
inputContainer2.setVisible(true);
instructions.setText("<html>\n" +
" <head>\n" +
instructions.setText("<html>\n" +
" <head>\n" +
" \n" +
" </head>\n" +
" <body>\n" +
@ -243,25 +243,25 @@ public class WilkinsCoffee implements ActionListener {
" </body>\n" +
"</html>\n");
pathDisplay.setText("Export path: " + outPathTemp);
pathDisplay.setText("Export path: " + outPathTemp);
break;
case EXPORT_LOCATION:
page = Pages.DONE;
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/setupIconDONE.png")).getScaledInstance(96, 96, Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
} catch (IOException e) {
System.out.println("ERROR: Missing resource in Wilkins. Page will be without images.");
picLabel.setText("");
}
inputContainer2.setVisible(false);
Main.outpath = outPathTemp;
Main.repatch = true;
Main.writeConf();
break;
case EXPORT_LOCATION:
page = Pages.DONE;
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/setupIconDONE.png")).getScaledInstance(96, 96, Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
} catch (IOException e) {
System.out.println("ERROR: Missing resource in Wilkins. Page will be without images.");
picLabel.setText("");
}
inputContainer2.setVisible(false);
Main.outpath = outPathTemp;
Main.repatch = true;
Main.writeConf();
instructions.setText("<html>\n" +
" <head>\n" +
instructions.setText("<html>\n" +
" <head>\n" +
" \n" +
" </head>\n" +
" <body>\n" +
@ -271,48 +271,48 @@ public class WilkinsCoffee implements ActionListener {
" </body>\n" +
"</html>\n");
break;
case DONE:
frame.dispose();
new MissPiggy().Action();
break;
default:
throw new UnsupportedOperationException("ERROR: Setup page-flip event listener didn't drink any Wilkins Coffee. Get a programmer!");
}
}
}
break;
case DONE:
frame.dispose();
new MissPiggy().Action();
break;
default:
throw new UnsupportedOperationException("ERROR: Setup page-flip event listener didn't drink any Wilkins Coffee. Get a programmer!");
}
}
}
private void refreshChecklist() {
ImageIcon positive = new ImageIcon(Main.class.getResource("/lightPositive.png"));
ImageIcon negative = new ImageIcon(Main.class.getResource("/lightNegative.png"));
private void refreshChecklist() {
ImageIcon positive = new ImageIcon(Main.class.getResource("/lightPositive.png"));
ImageIcon negative = new ImageIcon(Main.class.getResource("/lightNegative.png"));
// enabling the continue button here leaves the previous one redundant,
// but it's needed to ensure we don't force a redownload if the setup is interrupted
// enabling the continue button here leaves the previous one redundant,
// but it's needed to ensure we don't force a redownload if the setup is interrupted
if(new File(Main.inpath + "data.psarc").exists()) {
checklistBase.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistBase.setIcon(negative);}
if(new File(Main.inpath + "data1.psarc").exists()) {
checklistPatch1.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistPatch1.setIcon(negative);}
if(new File(Main.inpath + "data2.psarc").exists()) {
checklistPatch2.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistPatch2.setIcon(negative);}
if(new File(Main.inpath + "dlc1.psarc").exists()) {
checklistHD.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistHD.setIcon(negative);}
if(new File(Main.inpath + "dlc2.psarc").exists()) {
checklistFury.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistFury.setIcon(negative);}
}
if(new File(Main.inpath + "data.psarc").exists()) {
checklistBase.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistBase.setIcon(negative);}
if(new File(Main.inpath + "data1.psarc").exists()) {
checklistPatch1.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistPatch1.setIcon(negative);}
if(new File(Main.inpath + "data2.psarc").exists()) {
checklistPatch2.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistPatch2.setIcon(negative);}
if(new File(Main.inpath + "dlc1.psarc").exists()) {
checklistHD.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistHD.setIcon(negative);}
if(new File(Main.inpath + "dlc2.psarc").exists()) {
checklistFury.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistFury.setIcon(negative);}
}
}