Deploy function completed - mostly

This commit is contained in:
Downforce Agent 2024-05-07 12:21:22 -05:00
parent 16337680a8
commit cd1d9eab3c
4 changed files with 286 additions and 13 deletions

View File

@ -8,16 +8,21 @@
<properties/>
<border type="none"/>
<children>
<component id="491c1" class="javax.swing.JTextArea" binding="consoleDisplay">
<scrollpane id="6830c" binding="scrollPane">
<constraints>
<grid row="0" column="0" 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>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="line" title="Please wait a few minutes. Progress is shown above." title-justification="2" title-position="5"/>
<children>
<component id="491c1" class="javax.swing.JTextArea" binding="consoleDisplay">
<constraints/>
<properties>
<text value="test"/>
<text value=""/>
</properties>
</component>
</children>
</scrollpane>
</children>
</grid>
</form>

View File

@ -16,25 +16,291 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.util.FileUtils;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class Gonzo {
JFrame frame = new JFrame();
private JPanel frameContainer;
private JTextArea consoleDisplay;
private JScrollPane scrollPane;
public boolean data0;
public boolean data1;
public boolean data2;
public boolean dlc1;
public boolean dlc2;
private MissPiggy invoker;
public String oArcTarget = "dlc2.psarc"; // which psarc to rebuild the assets in
public void DeployMods() {
public void DeployMods(MissPiggy inv) {
invoker = inv;
System.out.println("\n\nStarting mod deployment\n\n");
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
frame.setSize(200, 100);
frame.setMinimumSize(new Dimension(200,100));
try {
BufferedImage windowIcon = ImageIO.read(new File(System.getProperty("user.dir") + "/resources/titleIcon.png"));
frame.setIconImage(windowIcon);
} catch (IOException e) {
System.out.println("ERROR: Failed to find /resources/titleIcon.png. Window will not have an icon.");
}
frame.setSize(800, 400);
frame.setMinimumSize(new Dimension(600,400));
frame.setTitle("Mod Installation");
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
frame.setVisible(true);
File psarcHandle = new File(Main.inpath + "data.psarc");
data0 = psarcHandle.isFile();
psarcHandle = new File(Main.inpath + "data1.psarc");
data1 = psarcHandle.isFile();
psarcHandle = new File(Main.inpath + "data2.psarc");
data2 = psarcHandle.isFile();
psarcHandle = new File(Main.inpath + "dlc1.psarc");
dlc1 = psarcHandle.isFile();
psarcHandle = new File(Main.inpath + "dlc2.psarc");
dlc2 = psarcHandle.isFile();
System.out.println("Source files discovered: data " + data0 + ", data1 " + data1 + ", data2 " + data2 + ", dlc1 " + dlc1 + ", dlc2 " + dlc2);
final Thread managerThread = new Thread() {
@Override
public void run() {
if (!Main.wine) {
POSIXRoutine();
} else {
Win32Routine();
}
}
};
managerThread.start();
}
private void POSIXRoutine() {
// create temporary working area for asset dump
new File(System.getProperty("user.home") + "/.firestar/temp/").mkdirs();
// decide which files to dump
List<String> dumpThese = new ArrayList<String>();
if (data0) {dumpThese.add("data.psarc");oArcTarget = "data.psarc";}
if (data1) {dumpThese.add("data1.psarc");oArcTarget = "data1.psarc";}
if (data2) {dumpThese.add("data2.psarc");oArcTarget = "data2.psarc";}
if (dlc1) {dumpThese.add("dlc1.psarc");oArcTarget = "dlc1.psarc";}
if (dlc2) {dumpThese.add("dlc2.psarc");oArcTarget = "dlc2.psarc";}
// dump all assets to working area
for (String s : dumpThese) {
try {
System.out.println("Firestar is extracting " + s);
consoleDisplay.append("Firestar is extracting " + s + "\n");
//Process p = Runtime.getRuntime().exec(new String[]{"bash","-c","aplay /home/bonkyboo/kittens_loop.wav"}); // DEBUG
Process p = Runtime.getRuntime().exec(new String[]{"bash","-c","cd " + System.getProperty("user.home") + "/.firestar/temp/" + ";wine ../psp2psarc.exe extract -y ../" + s});
final Thread ioThread = new Thread() {
@Override
public void run() {
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
consoleDisplay.append(line + "\n");
try {scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());}
catch (Exception e) {System.out.println("WARNING: Swing failed to paint window due to race condition.\n" + e.getMessage());}
}
reader.close();
} catch (final Exception e) {
e.printStackTrace(); // will probably definitely absolutely for sure hang firestar unless we do something. Too bad!
}
}
};
ioThread.start();
p.waitFor();
} catch (IOException | InterruptedException e) {
System.out.println(e.getMessage());
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
break;
}
}
// 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 (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")));
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 {
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();
}
}
}
} catch (IOException e) {
System.out.println(e.getMessage());
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
break;
}
}
// create a list of the contents of data/ for psp2psarc.exe to read from
List<String> oFilesList = new ArrayList<String>();
List<String> oFilesList2 = new ArrayList<String>();
try {
listAllFiles(Paths.get(System.getProperty("user.home") + "/.firestar/temp/data/"), oFilesList);
for (String p : oFilesList) {
// We need to clean up the path here on Linux to avoid psp2psarc getting confused about where the hell "/" is.
// In WINE it should see it as Z: by default, but if it's somewhere else then I don't have an elegant way of knowing what drive letter it's on, so
// relative paths are kind of the only choice here. This can be extended to Windows too as it works there, though completely unnecessary.
oFilesList2.add(p.replace("\\", "/").split(System.getProperty("user.home") + "/.firestar/temp/data/")[1]);
}
//oFilesList2.forEach(System.out::println); //debug
File oFilesListO = new File(System.getProperty("user.home") + "/.firestar/temp/list.txt");
if (oFilesListO.isFile()) {oFilesListO.delete();}
FileWriter oFilesListWr = new FileWriter(oFilesListO, true);
int i = 0;
for (String p : oFilesList2) {
oFilesListWr.append(p);
if (i != oFilesList2.size()) {
oFilesListWr.append("\n");
}
i++;
}
oFilesListWr.close();
} catch (IOException e) {
System.out.println(e.getMessage());
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
}
// invoke psp2psarc.exe one final time to reconstruct the assets
try {
System.out.println("Firestar is compiling the final build");
consoleDisplay.append("Firestar is compiling the final build" + "\n");
Process p = Runtime.getRuntime().exec(new String[]{"bash","-c","cd " + System.getProperty("user.home") + "/.firestar/temp/data" + ";wine ../../psp2psarc.exe create --skip-missing-files -j12 -a -i --input-file=../list.txt -o ../" + oArcTarget});
final Thread ioThread = new Thread() {
@Override
public void run() {
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
consoleDisplay.append(line + "\n");
try {scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());}
catch (Exception e) {System.out.println("WARNING: Swing failed to paint window due to race condition.\n" + e.getMessage());}
}
reader.close();
} catch (final Exception e) {
e.printStackTrace(); // will probably definitely absolutely for sure hang firestar unless we do something. Too bad!
}
}
};
ioThread.start();
p.waitFor();
} catch (IOException | InterruptedException e) {
System.out.println(e.getMessage());
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
}
// cleanup
new File(Main.outpath).mkdirs();
new File(System.getProperty("user.home") + "/.firestar/temp/" + oArcTarget).renameTo(new File(Main.outpath + oArcTarget));
try {
Process p = Runtime.getRuntime().exec(new String[]{"bash","-c","rm -rf " + System.getProperty("user.home") + "/.firestar/temp/"}); // Scary!
//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());
consoleDisplay.append("WARNING: Temporary files may not have been properly cleared.\n" + e.getMessage());
}
// done!
try {
TimeUnit.SECONDS.sleep(1); // avoid race condition when logging
} catch (InterruptedException e) {
//ignore
}
TitledBorder titledBorder = BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLACK), "DONE! Close this pop-up to continue.");
titledBorder.setTitlePosition(TitledBorder.BOTTOM);
titledBorder.setTitleJustification(TitledBorder.CENTER);
scrollPane.setBorder(titledBorder);
scrollPane.repaint();
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
}
private void Win32Routine() {
}
public void AllowExit() {
scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());
System.out.println("\n\nYou may now close the pop-up window.");
consoleDisplay.append("\n\n\nYou may now close the pop-up window.");
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
invoker.wrapUpDeployment();
e.getWindow().dispose();
}
});
}
private static void listAllFiles(Path currentPath, List<String> allFiles)
throws IOException
{
try (DirectoryStream<Path> stream = Files.newDirectoryStream(currentPath))
{
for (Path entry : stream) {
if (Files.isDirectory(entry)) {
listAllFiles(entry, allFiles);
} else {
allFiles.add(entry.toString());
}
}
}
}
}

View File

@ -32,7 +32,9 @@ public class Main {
public static final int vint = 0;
// User Settings
public static String outpath; //game assets location
// TODO: replace with user preference when config i/o is done
// also please double check that outpath is actually valid
public static String outpath = System.getProperty("user.home") + "/.firestar/out/"; //game assets location
public static String inpath = System.getProperty("user.home") + "/.firestar/"; //game assets location
public static boolean repatch; //are we in compat mode?
public static boolean wine; //are we on Linux, MINIX, BSD?

View File

@ -265,7 +265,7 @@ public class MissPiggy implements ActionListener {
frame.setEnabled(false);
// start
new Gonzo().DeployMods();
new Gonzo().DeployMods(this);
}
public void wrapUpDeployment() {