Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e52a6f8b79 | |||
| 3666485dd7 | |||
| 13878c3c74 | |||
| 213b8227e1 | |||
| bfb37d74d8 | |||
| 0a9d8d1bfd | |||
| c29448a521 | |||
| 81350dd06b | |||
| d839687040 | |||
| be3c42d7b4 | |||
| 59b070214c | |||
| 2c0e05865f | |||
| 3f286b5c91 | |||
| 2735c311ad | |||
| a9f0fc3f4c | |||
| f8146fd493 | |||
| d57f183785 | |||
| 9a267e4f8d | |||
| f6b8eeb29e | |||
| 679b4bc68e | |||
| b7d6ddd701 | |||
| 29dec51c2e | |||
| d79b360553 | |||
| bf0421552c | |||
| c7f2a84c3a | |||
| addd23b760 | |||
| 8cc7fca35c | |||
| 6078cb3bec | |||
| a7d261597e | |||
| 5d683bb893 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -26,4 +26,7 @@ bin/
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
/firestar.zip
|
||||
/run-linux.sh
|
||||
/run-win32.bat
|
||||
|
||||
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,18 +2,17 @@
|
||||
|
||||
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 & deleting mods
|
||||
- Repacking (installing) mods
|
||||
- config loading
|
||||
- Managing mods (install, add, delete, toggle on/off)
|
||||
- Cross-platform support
|
||||
|
||||
**What doesn't work yet:**
|
||||
- change load order, toggle
|
||||
- settings screen
|
||||
- misc. tools (pack creator, soundtrack mod generator...)
|
||||
- initial setup screen can still be a bit arduous for vita newbies
|
||||
|
||||
## Video Tutorial: [>> CLICK HERE <<](https://www.youtube.com/watch?v=Bi9fpqR2Ulw)
|
||||

|
||||
|
||||
# System Requirements
|
||||
|
||||
93
src/Clifford.form
Normal file
93
src/Clifford.form
Normal file
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="Clifford">
|
||||
<grid id="27dc6" binding="frameContainer" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="3294c" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Name"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="2e9e" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Author"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="e22ba" class="javax.swing.JTextField" binding="fName">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="9a381" class="javax.swing.JTextField" binding="fAuthor">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="c443e" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Version"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="d7be8" class="javax.swing.JTextField" binding="fVersion">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="e6d9e" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Description"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="4c6b" class="javax.swing.JTextPane" binding="fDescription">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="50"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="9d8aa" class="javax.swing.JButton" binding="savebtn">
|
||||
<constraints>
|
||||
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Save"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="8ded9" class="javax.swing.JButton" binding="cancelbtn">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Cancel"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
194
src/Clifford.java
Normal file
194
src/Clifford.java
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Firestar Mod Manager
|
||||
* Copyright (C) 2024 bonkmaykr
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
import net.lingala.zip4j.ZipFile;
|
||||
import net.lingala.zip4j.exception.ZipException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
|
||||
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;
|
||||
|
||||
MissPiggy invoker;
|
||||
Main.Mod mod;
|
||||
int index;
|
||||
File directory;
|
||||
|
||||
boolean creating;
|
||||
|
||||
public void Action(MissPiggy inv, int modindex) { // Editor
|
||||
invoker = inv;
|
||||
mod = Main.Mods.get(modindex);
|
||||
index = modindex;
|
||||
creating = false;
|
||||
|
||||
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);
|
||||
|
||||
fName.setText(mod.friendlyName);
|
||||
fAuthor.setText(mod.author);
|
||||
fVersion.setText(String.valueOf(mod.version));
|
||||
fDescription.setText(mod.description);
|
||||
|
||||
cancelbtn.addActionListener(this);
|
||||
savebtn.addActionListener(this);
|
||||
|
||||
frame.setVisible(true);
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e)
|
||||
{
|
||||
invoker.frame.setEnabled(true);
|
||||
e.getWindow().dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void Action(MissPiggy 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);
|
||||
|
||||
cancelbtn.addActionListener(this);
|
||||
savebtn.addActionListener(this);
|
||||
|
||||
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() == 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();
|
||||
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);
|
||||
}
|
||||
|
||||
Main.Mods.set(index, mod);
|
||||
invoker.frame.setEnabled(true);
|
||||
invoker.InitializeModListInGUI();
|
||||
frame.dispose();
|
||||
} else if (actionEvent.getSource() == savebtn && creating) {
|
||||
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());
|
||||
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"));
|
||||
}
|
||||
|
||||
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());
|
||||
container.put("loaderversion", 0); // TODO for later versions: Change depending on features inside of mod folder
|
||||
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);
|
||||
invoker.frame.setEnabled(true);
|
||||
frame.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
import net.lingala.zip4j.ZipFile;
|
||||
import net.lingala.zip4j.util.FileUtils;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
@@ -86,7 +87,7 @@ public class Gonzo {
|
||||
final Thread managerThread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (Main.repatch) {
|
||||
if (/*Main.repatch*/true) { //todo implement fast mode correctly or remove
|
||||
CompatibilityRoutine();
|
||||
} else {
|
||||
FastRoutine();
|
||||
@@ -151,49 +152,51 @@ public class Gonzo {
|
||||
// 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) {
|
||||
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/");
|
||||
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/");
|
||||
|
||||
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");
|
||||
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
|
||||
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: find all possible hazardous paths and blacklist them with regex
|
||||
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();
|
||||
for (String file : dQarray) {
|
||||
if(file.contains("..")) { //todo: find all possible hazardous paths and blacklist them with regex
|
||||
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();
|
||||
// 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;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,6 +275,7 @@ public class Gonzo {
|
||||
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);
|
||||
@@ -284,11 +288,9 @@ public class Gonzo {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Process p;
|
||||
if (!Main.windows) {p = Runtime.getRuntime().exec(new String[]{"bash","-c","rm -rf " + System.getProperty("user.home") + "/.firestar/temp/"});} // Scary!
|
||||
else {p = Runtime.getRuntime().exec(new String[]{"rmdir", new String(System.getProperty("user.home") + "/.firestar/temp/").replace("/", "\\").replace("\\", "\\\\"), "/s", "/q"});}
|
||||
//new File(System.getProperty("user.home") + "/.firestar/temp/").delete();
|
||||
} catch (IOException e) {
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ import javax.swing.JOptionPane;
|
||||
|
||||
public class Main {
|
||||
// Build Information
|
||||
public static final String vstr = "Beta 1";
|
||||
public static final String vcode = "Natasha";
|
||||
public static final String vstr = "Release 1.0";
|
||||
public static final String vcode = "Dekka";
|
||||
public static final int vint = 0;
|
||||
|
||||
// User Settings
|
||||
@@ -48,6 +48,7 @@ public class Main {
|
||||
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;
|
||||
}
|
||||
|
||||
// Mods
|
||||
@@ -55,7 +56,7 @@ public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// license string
|
||||
System.out.printf("FIRESTAR MOD MANAGER for WipEout 2048\nversion " + vstr + " (codename " + vcode + ")\n" +
|
||||
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" +
|
||||
@@ -127,4 +128,16 @@ public class Main {
|
||||
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,6 +29,8 @@ import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.math.RoundingMode;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.*;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
@@ -39,6 +41,7 @@ import java.util.Random;
|
||||
import java.util.regex.Pattern;
|
||||
import net.lingala.zip4j.*;
|
||||
import net.lingala.zip4j.exception.ZipException;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import static java.nio.file.StandardCopyOption.*;
|
||||
|
||||
@@ -72,6 +75,7 @@ public class MissPiggy implements ActionListener {
|
||||
//private int selectedItem;
|
||||
|
||||
public String priorityList;
|
||||
public String blackList;
|
||||
|
||||
public boolean listenersAlreadySet = false; // was written to troubleshoot a bug but this wasn't actually the cause
|
||||
|
||||
@@ -87,9 +91,10 @@ 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 JSeparator());
|
||||
fileMenu.add(new JMenuItem("Delete All"));
|
||||
fileMenu.add(new JSeparator());
|
||||
fileMenu.add(new JMenuItem("Options"));
|
||||
fileMenu.add(new JMenuItem("Quit"));
|
||||
@@ -99,6 +104,11 @@ public class MissPiggy implements ActionListener {
|
||||
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
|
||||
|
||||
helpMenu.add(new JMenuItem("Manual"));
|
||||
helpMenu.add(new JSeparator());
|
||||
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"));
|
||||
|
||||
menuBar.add(fileMenu);
|
||||
@@ -119,7 +129,11 @@ 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);
|
||||
helpMenu.getItem(2).addActionListener(this);
|
||||
helpMenu.getItem(3).addActionListener(this);
|
||||
helpMenu.getItem(5).addActionListener(this);
|
||||
|
||||
deployButton.addActionListener(this);
|
||||
importButton.addActionListener(this);
|
||||
@@ -181,11 +195,14 @@ public class MissPiggy implements ActionListener {
|
||||
|
||||
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]+=*") &&
|
||||
new File(System.getProperty("user.home") + "/.firestar/mods/" + s.substring(s.indexOf("=") + 1)).exists()) {
|
||||
mod.exists()) {
|
||||
//append mod to list from substring
|
||||
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);
|
||||
|
||||
//get json metadata from zip comment
|
||||
@@ -203,11 +220,39 @@ public class MissPiggy implements ActionListener {
|
||||
Main.Mods.add(m);
|
||||
} catch (Exception e) {
|
||||
System.out.println("WARNING: mod entry for " + s + " was found but does not contain valid JSON metadata. skipping");
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
} else {
|
||||
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 = "";
|
||||
}
|
||||
|
||||
// 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() {
|
||||
@@ -224,7 +269,8 @@ public class MissPiggy implements ActionListener {
|
||||
/*JLabel[]*/String[] contents = new String[Main.Mods.size()];
|
||||
System.out.println("Initializing modList to GUI with length of " + Main.Mods.size() + " units"); //debug
|
||||
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
|
||||
String authorDisplay;
|
||||
@@ -255,21 +301,61 @@ public class MissPiggy implements ActionListener {
|
||||
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() == toggleButton) {toggleSelected(modList.getSelectedIndex());} else
|
||||
if (actionEvent.getSource() == deleteButton1) {deleteSelected();} else
|
||||
|
||||
if (actionEvent.getSource() == helpMenu.getItem(0)) {new Rowlf().displayAboutScreen();}
|
||||
if (actionEvent.getSource() == toolsMenu.getItem(0)) {metaEditorGUI(modList.getSelectedIndex());} else
|
||||
if (actionEvent.getSource() == toolsMenu.getItem(1)) {generatorGUI();} 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/wiki/"));
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
JOptionPane.showMessageDialog(frame, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
} else
|
||||
if (actionEvent.getSource() == helpMenu.getItem(2)) {
|
||||
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(3)) {
|
||||
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(5)) {new Rowlf().displayAboutScreen();}
|
||||
}
|
||||
|
||||
// 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 i = 0;
|
||||
for (Main.Mod m : Main.Mods) {
|
||||
if (m.enabled) {i++;}
|
||||
}
|
||||
|
||||
// start
|
||||
new Gonzo().DeployMods(this);
|
||||
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
|
||||
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
frame.setEnabled(false);
|
||||
|
||||
// start
|
||||
new Gonzo().DeployMods(this);
|
||||
}
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(frame, "Please add at least one mod file to continue.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
public void wrapUpDeployment() {
|
||||
@@ -283,7 +369,7 @@ public class MissPiggy implements ActionListener {
|
||||
fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
|
||||
//fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("All", "zip", "agr", "agrc", "agrf", "fstar"));
|
||||
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("ZIP Archive", "zip"));
|
||||
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Firestar Mod Package", "agr", "agrc", "agrf", "fstar")); //what about fstar?
|
||||
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Firestar Mod Package", "fstar"));
|
||||
|
||||
int result = fileChooser.showOpenDialog(frame);
|
||||
|
||||
@@ -291,28 +377,37 @@ public class MissPiggy implements ActionListener {
|
||||
File selectedFile = fileChooser.getSelectedFile();
|
||||
System.out.println("Importing selected mod file \"" + selectedFile.getName() + "\"");
|
||||
|
||||
ZipFile zipImporterHandler = new ZipFile(selectedFile.getPath());
|
||||
ZipFile zipImporterHandler = new ZipFile(selectedFile.getAbsolutePath());
|
||||
if (zipImporterHandler.isValidZipFile()) {
|
||||
try {
|
||||
Path importDestination = Paths.get(System.getProperty("user.home") + "/.firestar/mods/"
|
||||
JSONObject json = new JSONObject(new ZipFile(selectedFile.getAbsolutePath()).getComment()); // intentionally trigger exception if file is random BS
|
||||
if ((int)json.get("loaderversion") <= Main.vint) {
|
||||
Path importDestination = Paths.get(System.getProperty("user.home") + "/.firestar/mods/"
|
||||
+ selectedFile.getName() + "_" + Main.Mods.size() + ".zip");
|
||||
Files.copy(Paths.get(selectedFile.getPath()), importDestination, StandardCopyOption.REPLACE_EXISTING);
|
||||
String importDestinationName = importDestination.toFile().getName();
|
||||
Files.copy(Paths.get(selectedFile.getPath()), importDestination, StandardCopyOption.REPLACE_EXISTING);
|
||||
String importDestinationName = importDestination.toFile().getName();
|
||||
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(System.getProperty("user.home") + "/.firestar/mods/index", true));
|
||||
bw.write(Main.Mods.size() + "=" + importDestinationName);
|
||||
bw.newLine();
|
||||
bw.close();
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(System.getProperty("user.home") + "/.firestar/mods/index", true));
|
||||
bw.write(Main.Mods.size() + "=" + importDestinationName);
|
||||
bw.newLine();
|
||||
bw.close();
|
||||
|
||||
InitializeModListStructure();
|
||||
InitializeModListInGUI();
|
||||
InitializeModListStructure();
|
||||
InitializeModListInGUI();
|
||||
} else {
|
||||
System.out.println("ERROR: This mod requires feature level " + json.get("loaderversion").toString() + ", but you have level " + Main.vint + ".");
|
||||
JOptionPane.showMessageDialog(frame, "This mod requires feature level " + json.get("loaderversion").toString() + ", but you have level " + Main.vint + ".\nPlease update Firestar to the latest version.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
System.out.println("ERROR: File is not a valid ZIP archive with mod data. Aborting.");
|
||||
JOptionPane.showMessageDialog(frame, "Whoops, that's not a valid mod file.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
JOptionPane.showMessageDialog(frame, "An error has occured.\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
} else {
|
||||
System.out.println("ERROR: File is not a valid ZIP archive. Aborting.");
|
||||
JOptionPane.showMessageDialog(frame, "Whoops, that's not a valid ZIP archive.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
System.out.println("ERROR: File is not a valid ZIP archive with mod data. Aborting.");
|
||||
JOptionPane.showMessageDialog(frame, "Whoops, that's not a valid mod file.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -322,38 +417,55 @@ public class MissPiggy implements ActionListener {
|
||||
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();
|
||||
Main.deleteDir(new File(System.getProperty("user.home") + "/.firestar/mods/"));
|
||||
Main.Mods.clear();
|
||||
|
||||
InitializeModListStructure();
|
||||
InitializeModListInGUI();
|
||||
InitializeModListStructure();
|
||||
InitializeModListInGUI();
|
||||
}
|
||||
}
|
||||
|
||||
public void optionsGUI() {
|
||||
// todo settings page w/ reset switch
|
||||
throwUnimplemented();
|
||||
new Waldorf().Action(this);
|
||||
frame.setEnabled(false);
|
||||
}
|
||||
|
||||
public void deleteSelected() {
|
||||
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);
|
||||
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());
|
||||
regenerateModBlacklist(false);
|
||||
regenerateModIndex(true);
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(frame, "Please select a mod to delete first.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
public void generatorGUI() {
|
||||
// todo mod packer
|
||||
throwUnimplemented();
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
int result = fileChooser.showOpenDialog(frame);
|
||||
if (result == JFileChooser.APPROVE_OPTION) {
|
||||
if (fileChooser.getSelectedFile().isDirectory()
|
||||
&& new File(fileChooser.getSelectedFile().getAbsolutePath() + "/data").isDirectory()) {
|
||||
File file = fileChooser.getSelectedFile();
|
||||
new Clifford().Action(this, file);
|
||||
frame.setEnabled(false);
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(frame, "You must select a folder containing a \"data\" directory with game assets.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void metaEditorGUI() {
|
||||
// todo tag editor
|
||||
throwUnimplemented();
|
||||
public void metaEditorGUI(int index) {
|
||||
if (index >= 0) {
|
||||
new Clifford().Action(this, index);
|
||||
frame.setEnabled(false);
|
||||
} else {
|
||||
JOptionPane.showMessageDialog(frame, "Please select a mod to edit first.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private void moveUp(int index) {
|
||||
@@ -374,8 +486,17 @@ public class MissPiggy implements ActionListener {
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
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
|
||||
@@ -439,7 +560,6 @@ public class MissPiggy implements ActionListener {
|
||||
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) {
|
||||
@@ -448,6 +568,7 @@ public class MissPiggy implements ActionListener {
|
||||
i++;
|
||||
}
|
||||
bw.close();
|
||||
System.out.println("Mod index file regenerated.");
|
||||
|
||||
if(reload) {
|
||||
Main.Mods.clear(); //cleanup
|
||||
@@ -455,7 +576,38 @@ public class MissPiggy implements ActionListener {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
74
src/Waldorf.form
Normal file
74
src/Waldorf.form
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="Waldorf">
|
||||
<grid id="27dc6" binding="frameContainer" layout-manager="GridLayoutManager" row-count="5" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<maximumSize width="50" height="100"/>
|
||||
<minimumSize width="50" height="100"/>
|
||||
<preferredSize width="50" height="100"/>
|
||||
</properties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="3d88f" class="javax.swing.JButton" binding="okbtn">
|
||||
<constraints>
|
||||
<grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Save"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="86775" class="javax.swing.JTextField" binding="fOutpath">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="db731" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Mod Export Path"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="50d13" class="javax.swing.JButton" binding="cancelbtn">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Cancel"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="252b3" class="javax.swing.JButton" binding="resetbtn">
|
||||
<constraints>
|
||||
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Restore Defaults"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="e2cd7" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="3" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=".firestar Folder"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="c68f2" class="javax.swing.JButton" binding="bOpenFolder">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="3" col-span="2" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<label value="Browse"/>
|
||||
<text value="Browse"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
104
src/Waldorf.java
Normal file
104
src/Waldorf.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Firestar Mod Manager
|
||||
* Copyright (C) 2024 bonkmaykr
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
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 JTextField fOutpath;
|
||||
private JButton resetbtn;
|
||||
private JButton bOpenFolder;
|
||||
MissPiggy invoker;
|
||||
|
||||
public void Action(MissPiggy inv) {
|
||||
invoker = inv;
|
||||
|
||||
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);
|
||||
okbtn.addActionListener(this);
|
||||
resetbtn.addActionListener(this);
|
||||
bOpenFolder.addActionListener(this);
|
||||
|
||||
fOutpath.setText(Main.outpath);
|
||||
|
||||
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 = fOutpath.getText();
|
||||
Main.writeConf();
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user