Compare commits
14
Commits
beta-1
..
addd23b760
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
addd23b760 | ||
|
|
8cc7fca35c | ||
|
|
6078cb3bec | ||
|
|
a7d261597e | ||
|
|
5d683bb893 | ||
|
|
fcb71d4600 | ||
|
|
8ebec68caf | ||
|
|
002d995c05 | ||
|
|
9780c3cc4f | ||
|
|
8107aaa5d5 | ||
|
|
6d772f0949 | ||
|
|
d8902af148 | ||
|
|
2e1fe95670 | ||
|
|
45fbe80f9f |
No files matched your search
Generated
+19
@@ -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,16 @@
|
||||
|
||||
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:**
|
||||
- Importing mods
|
||||
- Repacking (installing) mods
|
||||
- config loading
|
||||
- Basic stuff (installing mods, removing, reordering, persistent settings)
|
||||
- Cross-platform support
|
||||
|
||||
**What doesn't work yet:**
|
||||
- managing mods within the program (delete, change priority, toggle)
|
||||
- toggle mods on/off
|
||||
- settings screen
|
||||
- misc. tools (pack creator, soundtrack mod generator...)
|
||||
- initial setup screen can still be a bit arduous for vita newbies
|
||||
|
||||

|
||||
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ public class Kermit implements ActionListener {
|
||||
button.setVisible(false);frame.remove(button);
|
||||
button2.setVisible(false);frame.remove(button2);
|
||||
dialogText.setVisible(false);frame.remove(dialogText);
|
||||
changePage(Pages.EXPORT_MODE);
|
||||
changePage(Pages.SDK_INSTALL); // EXPORT_MODE
|
||||
break;
|
||||
case EXPORT_MODE:
|
||||
button.setVisible(false);frame.remove(button);
|
||||
|
||||
+155
-50
@@ -31,7 +31,10 @@ import java.io.IOException;
|
||||
import java.math.RoundingMode;
|
||||
import java.nio.file.*;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.regex.Pattern;
|
||||
import net.lingala.zip4j.*;
|
||||
@@ -66,10 +69,12 @@ public class MissPiggy implements ActionListener {
|
||||
private JButton deployButton;
|
||||
private JTextPane descriptionField;
|
||||
|
||||
private int selectedItem;
|
||||
//private int selectedItem;
|
||||
|
||||
public String priorityList;
|
||||
|
||||
public boolean listenersAlreadySet = false; // was written to troubleshoot a bug but this wasn't actually the cause
|
||||
|
||||
// Initialize the main window
|
||||
public void Action(/*Main entryPoint*/) {
|
||||
System.out.println("Main window created");
|
||||
@@ -82,9 +87,9 @@ public class MissPiggy implements ActionListener {
|
||||
toolsMenu = new JMenu("Tools");
|
||||
helpMenu = new JMenu("Help");
|
||||
|
||||
fileMenu.add(new JMenuItem("Deploy All Mods"));
|
||||
fileMenu.add(new JMenuItem("Import Mod..."));
|
||||
fileMenu.add(new JMenuItem("Remove All"));
|
||||
fileMenu.add(new JMenuItem("Deploy Mods"));
|
||||
fileMenu.add(new JMenuItem("Import Mod from File"));
|
||||
fileMenu.add(new JMenuItem("Delete All"));
|
||||
fileMenu.add(new JSeparator());
|
||||
fileMenu.add(new JMenuItem("Options"));
|
||||
fileMenu.add(new JMenuItem("Quit"));
|
||||
@@ -114,6 +119,7 @@ public class MissPiggy implements ActionListener {
|
||||
fileMenu.getItem(5).addActionListener(this);
|
||||
toolsMenu.getItem(0).addActionListener(this);
|
||||
toolsMenu.getItem(1).addActionListener(this);
|
||||
toolsMenu.getItem(2).addActionListener(this);
|
||||
helpMenu.getItem(0).addActionListener(this);
|
||||
|
||||
deployButton.addActionListener(this);
|
||||
@@ -125,38 +131,6 @@ public class MissPiggy implements ActionListener {
|
||||
toggleButton.addActionListener(this);
|
||||
|
||||
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
|
||||
try {
|
||||
@@ -237,8 +211,9 @@ public class MissPiggy implements ActionListener {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
public void InitializeModListInGUI() {
|
||||
// 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.");
|
||||
modList.clearSelection();
|
||||
modList.removeAll();
|
||||
@@ -260,6 +235,7 @@ public class MissPiggy implements ActionListener {
|
||||
i++;
|
||||
}
|
||||
modList.setListData(contents);
|
||||
createSelectionEventListener();
|
||||
}
|
||||
|
||||
private ListSelectionListener whenItemSelected() {
|
||||
@@ -277,10 +253,15 @@ public class MissPiggy implements ActionListener {
|
||||
if (actionEvent.getSource() == optionsButton) {optionsGUI();} else
|
||||
if (actionEvent.getSource() == fileMenu.getItem(4)) {optionsGUI();} else
|
||||
|
||||
if (actionEvent.getSource() == moveUpButton) {throwUnimplemented();} else // todo
|
||||
if (actionEvent.getSource() == moveDownButton) {throwUnimplemented();} else // todo
|
||||
if (actionEvent.getSource() == moveUpButton) {moveUp(modList.getSelectedIndex());} else
|
||||
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() == 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)) {new Rowlf().displayAboutScreen();}
|
||||
}
|
||||
@@ -288,12 +269,15 @@ public class MissPiggy implements ActionListener {
|
||||
// Will likely split the below functions into separate classes to work with intellij GUI designer.
|
||||
|
||||
public void deployModGUI() {
|
||||
// prevent interruptions
|
||||
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
frame.setEnabled(false);
|
||||
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
|
||||
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
frame.setEnabled(false);
|
||||
|
||||
// start
|
||||
new Gonzo().DeployMods(this);
|
||||
// start
|
||||
new Gonzo().DeployMods(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void wrapUpDeployment() {
|
||||
@@ -343,7 +327,19 @@ public class MissPiggy implements ActionListener {
|
||||
|
||||
public void removeAllGUI() {
|
||||
// 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) {
|
||||
for (Main.Mod entry : Main.Mods) {
|
||||
new File(System.getProperty("user.home") + "/.firestar/mods/" + entry.path).delete();
|
||||
}
|
||||
|
||||
new File(System.getProperty("user.home") + "/.firestar/mods/index").delete();
|
||||
Main.Mods.clear();
|
||||
|
||||
InitializeModListStructure();
|
||||
InitializeModListInGUI();
|
||||
}
|
||||
}
|
||||
|
||||
public void optionsGUI() {
|
||||
@@ -351,6 +347,18 @@ public class MissPiggy implements ActionListener {
|
||||
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() {
|
||||
// todo mod packer
|
||||
throwUnimplemented();
|
||||
@@ -361,12 +369,109 @@ public class MissPiggy implements ActionListener {
|
||||
throwUnimplemented();
|
||||
}
|
||||
|
||||
public void aboutGUI() {
|
||||
// todo about page
|
||||
throwUnimplemented();
|
||||
private void moveUp(int index) {
|
||||
if (index > 0) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if(reload) {
|
||||
Main.Mods.clear(); //cleanup
|
||||
priorityList = "";
|
||||
InitializeModListStructure();
|
||||
InitializeModListInGUI();
|
||||
}
|
||||
System.out.println("Mod index file regenerated.");
|
||||
} 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