Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f286b5c91 | |||
| 2735c311ad | |||
| a9f0fc3f4c | |||
| f8146fd493 | |||
| d57f183785 | |||
| 9a267e4f8d | |||
| f6b8eeb29e | |||
| 679b4bc68e | |||
| b7d6ddd701 | |||
| 29dec51c2e | |||
| d79b360553 | |||
| bf0421552c | |||
| c7f2a84c3a | |||
| addd23b760 | |||
| 8cc7fca35c | |||
| 6078cb3bec | |||
| a7d261597e | |||
| 5d683bb893 | |||
| fcb71d4600 | |||
| 8ebec68caf | |||
| 002d995c05 | |||
| 9780c3cc4f | |||
| 8107aaa5d5 | |||
| 6d772f0949 | |||
| d8902af148 | |||
| 2e1fe95670 | |||
| 45fbe80f9f |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -27,3 +27,4 @@ bin/
|
|||||||
|
|
||||||
### Mac OS ###
|
### Mac OS ###
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
/firestar.zip
|
||||||
|
|||||||
19
.idea/artifacts/firestar.xml
generated
Normal file
19
.idea/artifacts/firestar.xml
generated
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<component name="ArtifactManager">
|
||||||
|
<artifact type="jpackage" name="firestar">
|
||||||
|
<output-path>$PROJECT_DIR$/out/artifacts/firestar</output-path>
|
||||||
|
<properties id="jpackage-properties">
|
||||||
|
<options>
|
||||||
|
<option name="version" value="natasha" />
|
||||||
|
<option name="copyright" value="(C) 2024 bonkmaykr" />
|
||||||
|
<option name="description" value="" />
|
||||||
|
<option name="vendor" value="Anti-Gravity Racing Federation" />
|
||||||
|
<option name="mainClass" value="Main" />
|
||||||
|
</options>
|
||||||
|
</properties>
|
||||||
|
<root id="root">
|
||||||
|
<element id="archive" name="firestar.jar">
|
||||||
|
<element id="module-output" name="firestar" />
|
||||||
|
</element>
|
||||||
|
</root>
|
||||||
|
</artifact>
|
||||||
|
</component>
|
||||||
@@ -2,17 +2,15 @@
|
|||||||
|
|
||||||
Firestar is a mod manager for WipEout 2048 which automatically handles sorting mods by priority and repacking game assets based on selected add-on packs. It runs on a desktop/laptop computer and aims to allow easy installation of mods for users who have only a surface level understanding of hacking the PSVita.
|
Firestar is a mod manager for WipEout 2048 which automatically handles sorting mods by priority and repacking game assets based on selected add-on packs. It runs on a desktop/laptop computer and aims to allow easy installation of mods for users who have only a surface level understanding of hacking the PSVita.
|
||||||
|
|
||||||
# about 85% complete
|
# about 95% complete
|
||||||
**What works:**
|
**What works:**
|
||||||
- Importing mods
|
- Managing mods (install, add, delete, toggle on/off)
|
||||||
- Repacking (installing) mods
|
|
||||||
- config loading
|
|
||||||
- Cross-platform support
|
- Cross-platform support
|
||||||
|
|
||||||
**What doesn't work yet:**
|
**What doesn't work yet:**
|
||||||
- managing mods within the program (delete, change priority, toggle)
|
|
||||||
- settings screen
|
- settings screen
|
||||||
- misc. tools (pack creator, soundtrack mod generator...)
|
- misc. tools (pack creator, soundtrack mod generator...)
|
||||||
|
- initial setup screen can still be a bit arduous for vita newbies
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import net.lingala.zip4j.ZipFile;
|
import net.lingala.zip4j.ZipFile;
|
||||||
|
import net.lingala.zip4j.util.FileUtils;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
@@ -86,7 +87,7 @@ public class Gonzo {
|
|||||||
final Thread managerThread = new Thread() {
|
final Thread managerThread = new Thread() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (Main.repatch) {
|
if (/*Main.repatch*/true) { //todo implement fast mode correctly or remove
|
||||||
CompatibilityRoutine();
|
CompatibilityRoutine();
|
||||||
} else {
|
} else {
|
||||||
FastRoutine();
|
FastRoutine();
|
||||||
@@ -151,6 +152,7 @@ public class Gonzo {
|
|||||||
// overwrite assets with custom ones from each mod and/or perform operations as specified in mod's delete list
|
// 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
|
// todo: implement RegEx functions after delete.txt
|
||||||
for (Main.Mod m : Main.Mods) {
|
for (Main.Mod m : Main.Mods) {
|
||||||
|
if (m.enabled) {
|
||||||
try {
|
try {
|
||||||
System.out.println("Firestar is extracting " + m.friendlyName + " by " + m.author);
|
System.out.println("Firestar is extracting " + m.friendlyName + " by " + m.author);
|
||||||
consoleDisplay.append("Firestar is extracting " + m.friendlyName + " by " + m.author + "\n");
|
consoleDisplay.append("Firestar is extracting " + m.friendlyName + " by " + m.author + "\n");
|
||||||
@@ -196,6 +198,7 @@ public class Gonzo {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create a list of the contents of data/ for psp2psarc.exe to read from
|
// create a list of the contents of data/ for psp2psarc.exe to read from
|
||||||
List<String> oFilesList = new ArrayList<String>();
|
List<String> oFilesList = new ArrayList<String>();
|
||||||
@@ -272,6 +275,7 @@ public class Gonzo {
|
|||||||
boolean one = new File(Main.outpath).mkdirs();
|
boolean one = new File(Main.outpath).mkdirs();
|
||||||
boolean two;
|
boolean two;
|
||||||
System.out.println("created export folder: " + one);
|
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));}
|
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));}
|
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);
|
System.out.println("moved file to destination: " + two);
|
||||||
@@ -284,11 +288,9 @@ public class Gonzo {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Process p;
|
File tmp = new File(System.getProperty("user.home") + "/.firestar/temp/");
|
||||||
if (!Main.windows) {p = Runtime.getRuntime().exec(new String[]{"bash","-c","rm -rf " + System.getProperty("user.home") + "/.firestar/temp/"});} // Scary!
|
Main.deleteDir(tmp);
|
||||||
else {p = Runtime.getRuntime().exec(new String[]{"rmdir", new String(System.getProperty("user.home") + "/.firestar/temp/").replace("/", "\\").replace("\\", "\\\\"), "/s", "/q"});}
|
} catch (Exception e) {
|
||||||
//new File(System.getProperty("user.home") + "/.firestar/temp/").delete();
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("WARNING: Temporary files may not have been properly cleared.\n" + e.getMessage());
|
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());
|
consoleDisplay.append("WARNING: Temporary files may not have been properly cleared.\n" + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ public class Kermit implements ActionListener {
|
|||||||
button.setVisible(false);frame.remove(button);
|
button.setVisible(false);frame.remove(button);
|
||||||
button2.setVisible(false);frame.remove(button2);
|
button2.setVisible(false);frame.remove(button2);
|
||||||
dialogText.setVisible(false);frame.remove(dialogText);
|
dialogText.setVisible(false);frame.remove(dialogText);
|
||||||
changePage(Pages.EXPORT_MODE);
|
changePage(Pages.SDK_INSTALL); // EXPORT_MODE
|
||||||
break;
|
break;
|
||||||
case EXPORT_MODE:
|
case EXPORT_MODE:
|
||||||
button.setVisible(false);frame.remove(button);
|
button.setVisible(false);frame.remove(button);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import javax.swing.JOptionPane;
|
|||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
// Build Information
|
// Build Information
|
||||||
public static final String vstr = "Beta 1";
|
public static final String vstr = "Beta 4";
|
||||||
public static final String vcode = "Natasha";
|
public static final String vcode = "Natasha";
|
||||||
public static final int vint = 0;
|
public static final int vint = 0;
|
||||||
|
|
||||||
@@ -48,6 +48,7 @@ public class Main {
|
|||||||
public String game; //TODO for multi game support
|
public String game; //TODO for multi game support
|
||||||
public int loaderversion = 0; //minimum required vint or feature level from Firestar
|
public int loaderversion = 0; //minimum required vint or feature level from Firestar
|
||||||
public String author; // if null, "Author is unknown."
|
public String author; // if null, "Author is unknown."
|
||||||
|
public boolean enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mods
|
// Mods
|
||||||
@@ -127,4 +128,16 @@ public class Main {
|
|||||||
System.out.println(e.getMessage());
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -29,9 +29,14 @@ import java.io.File;
|
|||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import net.lingala.zip4j.*;
|
import net.lingala.zip4j.*;
|
||||||
@@ -66,9 +71,12 @@ public class MissPiggy implements ActionListener {
|
|||||||
private JButton deployButton;
|
private JButton deployButton;
|
||||||
private JTextPane descriptionField;
|
private JTextPane descriptionField;
|
||||||
|
|
||||||
private int selectedItem;
|
//private int selectedItem;
|
||||||
|
|
||||||
public String priorityList;
|
public String priorityList;
|
||||||
|
public String blackList;
|
||||||
|
|
||||||
|
public boolean listenersAlreadySet = false; // was written to troubleshoot a bug but this wasn't actually the cause
|
||||||
|
|
||||||
// Initialize the main window
|
// Initialize the main window
|
||||||
public void Action(/*Main entryPoint*/) {
|
public void Action(/*Main entryPoint*/) {
|
||||||
@@ -82,9 +90,10 @@ public class MissPiggy implements ActionListener {
|
|||||||
toolsMenu = new JMenu("Tools");
|
toolsMenu = new JMenu("Tools");
|
||||||
helpMenu = new JMenu("Help");
|
helpMenu = new JMenu("Help");
|
||||||
|
|
||||||
fileMenu.add(new JMenuItem("Deploy All Mods"));
|
fileMenu.add(new JMenuItem("Deploy Mods"));
|
||||||
fileMenu.add(new JMenuItem("Import Mod..."));
|
fileMenu.add(new JMenuItem("Import Mod from File"));
|
||||||
fileMenu.add(new JMenuItem("Remove All"));
|
//fileMenu.add(new JSeparator());
|
||||||
|
fileMenu.add(new JMenuItem("Delete All"));
|
||||||
fileMenu.add(new JSeparator());
|
fileMenu.add(new JSeparator());
|
||||||
fileMenu.add(new JMenuItem("Options"));
|
fileMenu.add(new JMenuItem("Options"));
|
||||||
fileMenu.add(new JMenuItem("Quit"));
|
fileMenu.add(new JMenuItem("Quit"));
|
||||||
@@ -94,6 +103,9 @@ public class MissPiggy implements ActionListener {
|
|||||||
toolsMenu.add(new JMenuItem("Create Soundtrack Mod..."));
|
toolsMenu.add(new JMenuItem("Create Soundtrack Mod..."));
|
||||||
//toolsMenu.add(new JMenuItem("Download Mod from URL")); // TODO: implement. move option to File menu. should be ez
|
//toolsMenu.add(new JMenuItem("Download Mod from URL")); // TODO: implement. move option to File menu. should be ez
|
||||||
|
|
||||||
|
helpMenu.add(new JMenuItem("Source Code")); //replace with Website 'screwgravity.net' and 'Issue Tracker' gitea later
|
||||||
|
helpMenu.add(new JMenuItem("License"));
|
||||||
|
helpMenu.add(new JSeparator());
|
||||||
helpMenu.add(new JMenuItem("About Firestar"));
|
helpMenu.add(new JMenuItem("About Firestar"));
|
||||||
|
|
||||||
menuBar.add(fileMenu);
|
menuBar.add(fileMenu);
|
||||||
@@ -114,7 +126,10 @@ public class MissPiggy implements ActionListener {
|
|||||||
fileMenu.getItem(5).addActionListener(this);
|
fileMenu.getItem(5).addActionListener(this);
|
||||||
toolsMenu.getItem(0).addActionListener(this);
|
toolsMenu.getItem(0).addActionListener(this);
|
||||||
toolsMenu.getItem(1).addActionListener(this);
|
toolsMenu.getItem(1).addActionListener(this);
|
||||||
|
toolsMenu.getItem(2).addActionListener(this);
|
||||||
helpMenu.getItem(0).addActionListener(this);
|
helpMenu.getItem(0).addActionListener(this);
|
||||||
|
helpMenu.getItem(1).addActionListener(this);
|
||||||
|
helpMenu.getItem(3).addActionListener(this);
|
||||||
|
|
||||||
deployButton.addActionListener(this);
|
deployButton.addActionListener(this);
|
||||||
importButton.addActionListener(this);
|
importButton.addActionListener(this);
|
||||||
@@ -125,38 +140,6 @@ public class MissPiggy implements ActionListener {
|
|||||||
toggleButton.addActionListener(this);
|
toggleButton.addActionListener(this);
|
||||||
|
|
||||||
descriptionField.getDocument().putProperty("filterNewlines", Boolean.FALSE);
|
descriptionField.getDocument().putProperty("filterNewlines", Boolean.FALSE);
|
||||||
modList.addListSelectionListener(e -> {
|
|
||||||
String authorDisplay;
|
|
||||||
File pathReference = new File(System.getProperty("user.home") + "/.firestar/mods/" + Main.Mods.get(modList.getSelectedIndex()).path);
|
|
||||||
DecimalFormat df = new DecimalFormat("##.##");
|
|
||||||
df.setRoundingMode(RoundingMode.UP);
|
|
||||||
float modFileSize = pathReference.length(); //precise units
|
|
||||||
String modFileSizeStr = String.valueOf(modFileSize);
|
|
||||||
String modFileSizeUnits = "bytes"; //todo: don't show decimals for bytes
|
|
||||||
if (pathReference.length() >= 1024) {
|
|
||||||
modFileSizeStr = String.valueOf(df.format(modFileSize / 1024));
|
|
||||||
modFileSizeUnits = "Kilobytes";
|
|
||||||
}
|
|
||||||
if (pathReference.length() >= 1024 * 1024) {
|
|
||||||
modFileSizeStr = String.valueOf(df.format(modFileSize / (1024 * 1024)));
|
|
||||||
modFileSizeUnits = "Megabytes";
|
|
||||||
}
|
|
||||||
if (pathReference.length() >= 1024 * 1024 * 1024) {
|
|
||||||
modFileSizeStr = String.valueOf(df.format(modFileSize / (1024 * 1024 * 1024)));
|
|
||||||
modFileSizeUnits = "Gigabytes";
|
|
||||||
}
|
|
||||||
if (Main.Mods.get(modList.getSelectedIndex()).author == null) {
|
|
||||||
authorDisplay = "an Unknown Author";
|
|
||||||
} else {
|
|
||||||
authorDisplay = Main.Mods.get(modList.getSelectedIndex()).author;
|
|
||||||
}
|
|
||||||
descriptionField.setText(
|
|
||||||
"\"" + Main.Mods.get(modList.getSelectedIndex()).friendlyName + "\"\n" +
|
|
||||||
"by " + authorDisplay + "\n\n" +
|
|
||||||
"Version " + Main.Mods.get(modList.getSelectedIndex()).version + "\n" +
|
|
||||||
modFileSizeStr + " " + modFileSizeUnits + " in size" +
|
|
||||||
"\n\n" + Main.Mods.get(modList.getSelectedIndex()).description
|
|
||||||
);});
|
|
||||||
|
|
||||||
// display window
|
// display window
|
||||||
try {
|
try {
|
||||||
@@ -208,11 +191,14 @@ public class MissPiggy implements ActionListener {
|
|||||||
|
|
||||||
06/29/24 - also skip files that were manually removed but remain in the list
|
06/29/24 - also skip files that were manually removed but remain in the list
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
File mod = new File(System.getProperty("user.home") + "/.firestar/mods/" + s.substring(s.indexOf("=") + 1).trim());
|
||||||
|
|
||||||
if (s.split("=")[0].matches("[0-9]+=*") &&
|
if (s.split("=")[0].matches("[0-9]+=*") &&
|
||||||
new File(System.getProperty("user.home") + "/.firestar/mods/" + s.substring(s.indexOf("=") + 1)).exists()) {
|
mod.exists()) {
|
||||||
//append mod to list from substring
|
//append mod to list from substring
|
||||||
Main.Mod m = new Main().new Mod();
|
Main.Mod m = new Main().new Mod();
|
||||||
m.path = s.substring(s.indexOf("=") + 1);
|
m.path = s.substring(s.indexOf("=") + 1).trim();
|
||||||
System.out.println("found file " + m.path);
|
System.out.println("found file " + m.path);
|
||||||
|
|
||||||
//get json metadata from zip comment
|
//get json metadata from zip comment
|
||||||
@@ -230,15 +216,44 @@ public class MissPiggy implements ActionListener {
|
|||||||
Main.Mods.add(m);
|
Main.Mods.add(m);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("WARNING: mod entry for " + s + " was found but does not contain valid JSON metadata. skipping");
|
System.out.println("WARNING: mod entry for " + s + " was found but does not contain valid JSON metadata. skipping");
|
||||||
|
System.out.println(e.getMessage());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!s.isEmpty()) {System.out.println("WARNING: mod entry for " + s + " doesn't actually exist. skipping");}
|
if (!s.isEmpty()) {System.out.println("WARNING: mod entry for " + s + " doesn't actually exist. skipping");}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
blackList = new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "/.firestar/mods/blacklist")));
|
||||||
|
} catch (IOException e) {
|
||||||
|
File blackListFileHandle = new File(System.getProperty("user.home") + "/.firestar/mods/blacklist");
|
||||||
|
new File(System.getProperty("user.home") + "/.firestar/mods/").mkdirs();
|
||||||
|
if(!blackListFileHandle.isFile()){
|
||||||
|
try {
|
||||||
|
blackListFileHandle.createNewFile();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
blackList = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializeModListInGUI() { // i really wanted this to be "lights, camera, action" but the code organizing kept getting stupider and stupider so i gave up
|
// initialize data structures from each list entry
|
||||||
|
String[] bListArray = blackList.split("\n");
|
||||||
|
//Arrays.sort(bListArray);
|
||||||
|
System.out.println("Initializing blacklist from file with length of " + bListArray.length + " units"); //debug
|
||||||
|
for (String s : bListArray) {
|
||||||
|
for (Main.Mod m : Main.Mods) {
|
||||||
|
if (s.trim().equals(m.path)) {
|
||||||
|
m.enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitializeModListInGUI() {
|
||||||
// cleanup
|
// cleanup
|
||||||
|
if (listenersAlreadySet) {modList.removeListSelectionListener(modList.getListSelectionListeners()[0]);} // was written to troubleshoot a bug but this wasn't actually the cause
|
||||||
descriptionField.setText("Select a mod from the list on the right to view more details, or to make changes to your installation.");
|
descriptionField.setText("Select a mod from the list on the right to view more details, or to make changes to your installation.");
|
||||||
modList.clearSelection();
|
modList.clearSelection();
|
||||||
modList.removeAll();
|
modList.removeAll();
|
||||||
@@ -250,7 +265,8 @@ public class MissPiggy implements ActionListener {
|
|||||||
/*JLabel[]*/String[] contents = new String[Main.Mods.size()];
|
/*JLabel[]*/String[] contents = new String[Main.Mods.size()];
|
||||||
System.out.println("Initializing modList to GUI with length of " + Main.Mods.size() + " units"); //debug
|
System.out.println("Initializing modList to GUI with length of " + Main.Mods.size() + " units"); //debug
|
||||||
while (i < Main.Mods.size()) {
|
while (i < Main.Mods.size()) {
|
||||||
contents[i] = Main.Mods.get(i).friendlyName;
|
if (Main.Mods.get(i).enabled) {contents[i] = Main.Mods.get(i).friendlyName;}
|
||||||
|
else {contents[i] = Main.Mods.get(i).friendlyName + " (Disabled)";}
|
||||||
|
|
||||||
//debug
|
//debug
|
||||||
String authorDisplay;
|
String authorDisplay;
|
||||||
@@ -260,6 +276,7 @@ public class MissPiggy implements ActionListener {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
modList.setListData(contents);
|
modList.setListData(contents);
|
||||||
|
createSelectionEventListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ListSelectionListener whenItemSelected() {
|
private ListSelectionListener whenItemSelected() {
|
||||||
@@ -277,17 +294,46 @@ public class MissPiggy implements ActionListener {
|
|||||||
if (actionEvent.getSource() == optionsButton) {optionsGUI();} else
|
if (actionEvent.getSource() == optionsButton) {optionsGUI();} else
|
||||||
if (actionEvent.getSource() == fileMenu.getItem(4)) {optionsGUI();} else
|
if (actionEvent.getSource() == fileMenu.getItem(4)) {optionsGUI();} else
|
||||||
|
|
||||||
if (actionEvent.getSource() == moveUpButton) {throwUnimplemented();} else // todo
|
if (actionEvent.getSource() == moveUpButton) {moveUp(modList.getSelectedIndex());} else
|
||||||
if (actionEvent.getSource() == moveDownButton) {throwUnimplemented();} else // todo
|
if (actionEvent.getSource() == moveDownButton) {moveDown(modList.getSelectedIndex());} else
|
||||||
if (actionEvent.getSource() == toggleButton) {throwUnimplemented();} else // todo
|
|
||||||
if (actionEvent.getSource() == deleteButton1) {throwUnimplemented();} else // todo
|
|
||||||
|
|
||||||
if (actionEvent.getSource() == helpMenu.getItem(0)) {new Rowlf().displayAboutScreen();}
|
if (actionEvent.getSource() == toggleButton) {toggleSelected(modList.getSelectedIndex());} else
|
||||||
|
if (actionEvent.getSource() == deleteButton1) {deleteSelected();} else
|
||||||
|
|
||||||
|
if (actionEvent.getSource() == toolsMenu.getItem(0)) {throwUnimplemented();} else
|
||||||
|
if (actionEvent.getSource() == toolsMenu.getItem(1)) {throwUnimplemented();} else
|
||||||
|
if (actionEvent.getSource() == toolsMenu.getItem(2)) {throwUnimplemented();} else
|
||||||
|
|
||||||
|
if (actionEvent.getSource() == helpMenu.getItem(0)) {
|
||||||
|
try {
|
||||||
|
Desktop.getDesktop().browse(new URI("https://git.worlio.com/bonkmaykr/firestar"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
JOptionPane.showMessageDialog(frame, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (actionEvent.getSource() == helpMenu.getItem(1)) {
|
||||||
|
try {
|
||||||
|
Desktop.getDesktop().browse(new URI("https://www.gnu.org/licenses/gpl-3.0.en.html"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
JOptionPane.showMessageDialog(frame, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (actionEvent.getSource() == helpMenu.getItem(3)) {new Rowlf().displayAboutScreen();}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will likely split the below functions into separate classes to work with intellij GUI designer.
|
// Will likely split the below functions into separate classes to work with intellij GUI designer.
|
||||||
|
|
||||||
public void deployModGUI() {
|
public void deployModGUI() {
|
||||||
|
int i = 0;
|
||||||
|
for (Main.Mod m : Main.Mods) {
|
||||||
|
if (m.enabled) {i++;}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i > 0) {
|
||||||
|
int result = JOptionPane.showConfirmDialog(frame, "A new PSARC will be generated. This can take several minutes.\nDuring this time, your computer may be very busy or slow.\n\nAre you sure you want to continue?", "Deploy Mods", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
|
||||||
|
if (result == JOptionPane.YES_OPTION) {
|
||||||
// prevent interruptions
|
// prevent interruptions
|
||||||
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||||
frame.setEnabled(false);
|
frame.setEnabled(false);
|
||||||
@@ -295,6 +341,10 @@ public class MissPiggy implements ActionListener {
|
|||||||
// start
|
// start
|
||||||
new Gonzo().DeployMods(this);
|
new Gonzo().DeployMods(this);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
JOptionPane.showMessageDialog(frame, "Please add at least one mod file to continue.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void wrapUpDeployment() {
|
public void wrapUpDeployment() {
|
||||||
// restore functionality to main window
|
// restore functionality to main window
|
||||||
@@ -343,7 +393,15 @@ public class MissPiggy implements ActionListener {
|
|||||||
|
|
||||||
public void removeAllGUI() {
|
public void removeAllGUI() {
|
||||||
// todo warning dialog that nukes list when Yes is clicked
|
// todo warning dialog that nukes list when Yes is clicked
|
||||||
throwUnimplemented();
|
int result = JOptionPane.showConfirmDialog(frame, "Do you really want to delete all mods?", "Remove All", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
||||||
|
|
||||||
|
if (result == JOptionPane.YES_OPTION) {
|
||||||
|
Main.deleteDir(new File(System.getProperty("user.home") + "/.firestar/mods/"));
|
||||||
|
Main.Mods.clear();
|
||||||
|
|
||||||
|
InitializeModListStructure();
|
||||||
|
InitializeModListInGUI();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void optionsGUI() {
|
public void optionsGUI() {
|
||||||
@@ -351,6 +409,18 @@ public class MissPiggy implements ActionListener {
|
|||||||
throwUnimplemented();
|
throwUnimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deleteSelected() {
|
||||||
|
if (modList.getSelectedIndex() >= 0) {
|
||||||
|
File file = new File(System.getProperty("user.home") + "/.firestar/mods/" + Main.Mods.get(modList.getSelectedIndex()).path);
|
||||||
|
file.delete();
|
||||||
|
System.out.println("Deleted " + Main.Mods.get(modList.getSelectedIndex()).friendlyName); //debug
|
||||||
|
Main.Mods.remove(modList.getSelectedIndex());
|
||||||
|
regenerateModIndex(true);
|
||||||
|
} else {
|
||||||
|
JOptionPane.showMessageDialog(frame, "Please select a mod to delete first.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void generatorGUI() {
|
public void generatorGUI() {
|
||||||
// todo mod packer
|
// todo mod packer
|
||||||
throwUnimplemented();
|
throwUnimplemented();
|
||||||
@@ -361,12 +431,149 @@ public class MissPiggy implements ActionListener {
|
|||||||
throwUnimplemented();
|
throwUnimplemented();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void aboutGUI() {
|
private void moveUp(int index) {
|
||||||
// todo about page
|
if (index > 0) {
|
||||||
throwUnimplemented();
|
Collections.swap(Main.Mods, index, index - 1);
|
||||||
|
System.out.println("Items moved, redeploying list");
|
||||||
|
InitializeModListInGUI();
|
||||||
|
regenerateModIndex(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveDown(int index) {
|
||||||
|
if (index < (Main.Mods.size() - 1)) {
|
||||||
|
Collections.swap(Main.Mods, index, index + 1);
|
||||||
|
System.out.println("Items moved, redeploying list");
|
||||||
|
InitializeModListInGUI();
|
||||||
|
regenerateModIndex(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleSelected(int index) {
|
||||||
|
if (index >= 0) {
|
||||||
|
Main.Mods.get(index).enabled = !Main.Mods.get(index).enabled;
|
||||||
|
regenerateModBlacklist(true);
|
||||||
|
} else {
|
||||||
|
JOptionPane.showMessageDialog(frame, "Please select a mod to toggle first.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void throwUnimplemented() {
|
public void throwUnimplemented() {
|
||||||
JOptionPane.showMessageDialog(frame, "Unimplemented.\nSee README at https://git.worlio.com/bonkmaykr/firestar", "Unimplemented", JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.showMessageDialog(frame, "This feature is unimplemented and will be coming soon.\nSee README at https://git.worlio.com/bonkmaykr/firestar", "Unimplemented", JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createSelectionEventListener() { // moved incase needs to be removed and re-added
|
||||||
|
listenersAlreadySet = true; // was written to troubleshoot a bug but this wasn't actually the cause
|
||||||
|
modList.addListSelectionListener(e -> {
|
||||||
|
if (modList.getSelectedIndex() >= 0 && modList.getModel().getSize() >= 1) { // avoid race OOB when reinitializing mod list
|
||||||
|
String authorDisplay;
|
||||||
|
|
||||||
|
try { //debug
|
||||||
|
|
||||||
|
File pathReference = new File(System.getProperty("user.home") + "/.firestar/mods/" + Main.Mods.get(modList.getSelectedIndex()).path);
|
||||||
|
DecimalFormat df = new DecimalFormat("##.##");
|
||||||
|
df.setRoundingMode(RoundingMode.UP);
|
||||||
|
float modFileSize = pathReference.length(); //precise units
|
||||||
|
String modFileSizeStr = String.valueOf(modFileSize);
|
||||||
|
String modFileSizeUnits = "bytes"; //todo: don't show decimals for bytes
|
||||||
|
if (pathReference.length() >= 1024) {
|
||||||
|
modFileSizeStr = String.valueOf(df.format(modFileSize / 1024));
|
||||||
|
modFileSizeUnits = "Kilobytes";
|
||||||
|
}
|
||||||
|
if (pathReference.length() >= 1024 * 1024) {
|
||||||
|
modFileSizeStr = String.valueOf(df.format(modFileSize / (1024 * 1024)));
|
||||||
|
modFileSizeUnits = "Megabytes";
|
||||||
|
}
|
||||||
|
if (pathReference.length() >= 1024 * 1024 * 1024) {
|
||||||
|
modFileSizeStr = String.valueOf(df.format(modFileSize / (1024 * 1024 * 1024)));
|
||||||
|
modFileSizeUnits = "Gigabytes";
|
||||||
|
}
|
||||||
|
if (Main.Mods.get(modList.getSelectedIndex()).author == null) {
|
||||||
|
authorDisplay = "an Unknown Author";
|
||||||
|
} else {
|
||||||
|
authorDisplay = Main.Mods.get(modList.getSelectedIndex()).author;
|
||||||
|
}
|
||||||
|
descriptionField.setText(
|
||||||
|
"\"" + Main.Mods.get(modList.getSelectedIndex()).friendlyName + "\"\n" +
|
||||||
|
"by " + authorDisplay + "\n\n" +
|
||||||
|
"Version " + Main.Mods.get(modList.getSelectedIndex()).version + "\n" +
|
||||||
|
modFileSizeStr + " " + modFileSizeUnits + " in size" +
|
||||||
|
"\n\n" + Main.Mods.get(modList.getSelectedIndex()).description
|
||||||
|
);}
|
||||||
|
|
||||||
|
catch (IndexOutOfBoundsException ex) {
|
||||||
|
System.out.println(ex.getMessage());
|
||||||
|
System.out.println("mods " + Main.Mods.size());
|
||||||
|
System.out.println("mod display " + modList.getModel().getSize());
|
||||||
|
System.out.println("selection index " + modList.getSelectedIndex());
|
||||||
|
|
||||||
|
int result = JOptionPane.showConfirmDialog(frame, "Firestar encountered an internal error.\n" + ex.getMessage(), "Fatal Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE);
|
||||||
|
if (result == JOptionPane.OK_OPTION) {System.exit(1);} //user safety
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void regenerateModIndex(boolean reload) {
|
||||||
|
try {
|
||||||
|
System.out.println("Regenerating index..."); //debug
|
||||||
|
|
||||||
|
new File(System.getProperty("user.home") + "/.firestar/mods/index").delete();
|
||||||
|
File priorityListFileHandle = new File(System.getProperty("user.home") + "/.firestar/mods/index");
|
||||||
|
priorityListFileHandle.createNewFile();
|
||||||
|
|
||||||
|
BufferedWriter bw = new BufferedWriter(new FileWriter(System.getProperty("user.home") + "/.firestar/mods/index", true));
|
||||||
|
int i = 0;
|
||||||
|
for (Main.Mod m : Main.Mods) {
|
||||||
|
bw.write(i + "=" + m.path);
|
||||||
|
bw.newLine();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
bw.close();
|
||||||
|
System.out.println("Mod index file regenerated.");
|
||||||
|
|
||||||
|
if(reload) {
|
||||||
|
Main.Mods.clear(); //cleanup
|
||||||
|
priorityList = "";
|
||||||
|
InitializeModListStructure();
|
||||||
|
InitializeModListInGUI();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
JOptionPane.showMessageDialog(frame, "An error has occured.\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void regenerateModBlacklist(boolean reload) {
|
||||||
|
try {
|
||||||
|
System.out.println("Regenerating blacklist..."); //debug
|
||||||
|
|
||||||
|
new File(System.getProperty("user.home") + "/.firestar/mods/blacklist").delete();
|
||||||
|
File blackListFileHandle = new File(System.getProperty("user.home") + "/.firestar/mods/blacklist");
|
||||||
|
blackListFileHandle.createNewFile();
|
||||||
|
|
||||||
|
BufferedWriter bw2 = new BufferedWriter(new FileWriter(System.getProperty("user.home") + "/.firestar/mods/blacklist", true));
|
||||||
|
int i2 = 0;
|
||||||
|
for (Main.Mod m : Main.Mods) {
|
||||||
|
if (!m.enabled) {
|
||||||
|
bw2.write(m.path);
|
||||||
|
bw2.newLine();
|
||||||
|
i2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bw2.close();
|
||||||
|
System.out.println("Mod blacklist file regenerated.");
|
||||||
|
|
||||||
|
if(reload) {
|
||||||
|
Main.Mods.clear(); //cleanup
|
||||||
|
blackList = "";
|
||||||
|
InitializeModListStructure();
|
||||||
|
InitializeModListInGUI();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
JOptionPane.showMessageDialog(frame, "An error has occured.\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user