Compare commits
57 Commits
862c5d62a4
...
tetsuo-1.3
| Author | SHA1 | Date | |
|---|---|---|---|
| 9155493c0e | |||
| c32d45c63f | |||
| e53933200e | |||
|
|
8840a193a3 | ||
| c9a968d173 | |||
| b1f38400c3 | |||
| 889e99f301 | |||
| 9585f16f11 | |||
| f7c4603db1 | |||
| 9292d8db62 | |||
| b8dbfc9095 | |||
| f07a75276c | |||
| f336be5a0a | |||
| 841f8132bb | |||
| 5654fa0b9f | |||
| f21d05d245 | |||
| b5f2aa6925 | |||
| 12f01000dd | |||
| 168e536068 | |||
| 64230f5eb4 | |||
| 91a574bb04 | |||
| e877f5eaa6 | |||
| b3a949fe43 | |||
| a17f7d1b58 | |||
| efbf8585d2 | |||
| 3849a765e3 | |||
| 2bbf34bf70 | |||
| ca36fadad1 | |||
| a75f1ad06c | |||
| a54c1ea325 | |||
| 780a7d69b3 | |||
| 8dfed698bb | |||
| 040adf3b7e | |||
| 309aaec333 | |||
| 8af95d5287 | |||
| 9950188e0d | |||
| 3d91ebbbd7 | |||
| 52dbc56104 | |||
| 17bbae0d66 | |||
| 4aa017f7ac | |||
| a57e5695a5 | |||
| 009f406a4b | |||
| 2d7e0a1cb0 | |||
| b4b8b1ced5 | |||
| 7d26ed564e | |||
| 14a943edf3 | |||
| 408a52512b | |||
| 6e292212fd | |||
| a91ba62bf8 | |||
| 859ac41fde | |||
| acd1f0dfe8 | |||
| 7b7d4a206e | |||
| 1abe9519c8 | |||
| 82b351928b | |||
| 921df0cbd5 | |||
| f11dfc5378 | |||
| 68a0dcba49 |
2
.gitignore
vendored
@@ -28,6 +28,7 @@ out/
|
|||||||
### Mac OS ###
|
### Mac OS ###
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
### Binaries ###
|
||||||
/firestar.zip
|
/firestar.zip
|
||||||
/run-linux.sh
|
/run-linux.sh
|
||||||
/run-win32.bat
|
/run-win32.bat
|
||||||
@@ -37,3 +38,4 @@ out/
|
|||||||
/build/
|
/build/
|
||||||
/.gradle/
|
/.gradle/
|
||||||
/gradle/
|
/gradle/
|
||||||
|
!/gradle/wrapper/*
|
||||||
10
.idea/artifacts/firestar_jar.xml
generated
@@ -6,10 +6,14 @@
|
|||||||
<element id="file-copy" path="$PROJECT_DIR$/META-INF/MANIFEST.MF" />
|
<element id="file-copy" path="$PROJECT_DIR$/META-INF/MANIFEST.MF" />
|
||||||
</element>
|
</element>
|
||||||
<element id="module-output" name="firestar.firestar.main" />
|
<element id="module-output" name="firestar.firestar.main" />
|
||||||
<element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.json/json/20240303/ebb88e8fb5122b7506d5cf1d69f1ccdb790d22a/json-20240303.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/net.lingala.zip4j/zip4j/2.11.5/4214e396e3891cb19eded3ce5e584cba9032fdc3/zip4j-2.11.5.jar" path-in-jar="/" />
|
|
||||||
<element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.jetbrains.intellij.java/java-gui-forms-rt/203.7148.30/f0dbca371a2592689e541be912de6005939f9c7c/java-gui-forms-rt-203.7148.30.jar" path-in-jar="/" />
|
|
||||||
<element id="dir-copy" path="$PROJECT_DIR$/firestar/src/main/resources" />
|
<element id="dir-copy" path="$PROJECT_DIR$/firestar/src/main/resources" />
|
||||||
|
<element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.jetbrains.intellij.java/java-gui-forms-rt/203.7148.30/f0dbca371a2592689e541be912de6005939f9c7c/java-gui-forms-rt-203.7148.30.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.github.java-diff-utils/java-diff-utils/4.12/1a712a91324d566eef39817fc5c9980eb10c21db/java-diff-utils-4.12.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/net.lingala.zip4j/zip4j/2.11.5/4214e396e3891cb19eded3ce5e584cba9032fdc3/zip4j-2.11.5.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-lang3/3.14.0/1ed471194b02f2c6cb734a0cd6f6f107c673afae/commons-lang3-3.14.0.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.apache.commons/commons-text/1.12.0/66aa90dc099701c4d3b14bd256c328f592ccf0d6/commons-text-1.12.0.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.json/json/20240303/ebb88e8fb5122b7506d5cf1d69f1ccdb790d22a/json-20240303.jar" path-in-jar="/" />
|
||||||
|
<element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.netbeans.external/org-apache-commons-io/RELEASE113/815893df5f31da2ece4040fe0a12fd44b577afaf/org-apache-commons-io-RELEASE113.jar" path-in-jar="/" />
|
||||||
</root>
|
</root>
|
||||||
</artifact>
|
</artifact>
|
||||||
</component>
|
</component>
|
||||||
10
.idea/libraries/apache_commons_io.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="apache.commons.io" type="repository">
|
||||||
|
<properties maven-id="commons-io:commons-io:2.16.1" />
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/commons-io/commons-io/2.16.1/commons-io-2.16.1.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
11
.idea/libraries/apache_commons_text.xml
generated
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<component name="libraryTable">
|
||||||
|
<library name="apache.commons.text" type="repository">
|
||||||
|
<properties maven-id="org.apache.commons:commons-text:1.12.0" />
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-text/1.12.0/commons-text-1.12.0.jar!/" />
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-lang3/3.14.0/commons-lang3-3.14.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</component>
|
||||||
10
.idea/uiDesigner.xml
generated
@@ -32,17 +32,17 @@
|
|||||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||||
</item>
|
</item>
|
||||||
|
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||||
<initial-values>
|
<initial-values>
|
||||||
<property name="text" value="Label" />
|
<property name="text" value="Label" />
|
||||||
</initial-values>
|
</initial-values>
|
||||||
</item>
|
</item>
|
||||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
|
||||||
<preferred-size width="150" height="-1" />
|
|
||||||
</default-constraints>
|
|
||||||
</item>
|
|
||||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
<preferred-size width="150" height="-1" />
|
<preferred-size width="150" height="-1" />
|
||||||
|
|||||||
50
README.md
@@ -1,6 +1,6 @@
|
|||||||

|

|
||||||
|
|
||||||
**Firestar is a cross-platform Java-based mod manager for WipEout 2048**, which runs on a desktop/laptop computer and aims to allow easy installation of mods for users with very little hassle. It is compatible with both real PSVita hardware, as well as emulators.
|
**Firestar is a cross-platform Java-based mod manager for WipEout 2048**, which runs on a desktop/laptop computer and aims to allow easy installation of mods with very little hassle. It is compatible with both real PSVita hardware, as well as with emulators.
|
||||||
|
|
||||||
## Get Started: [>> CLICK HERE <<](https://git.worlio.com/bonkmaykr/firestar/wiki)
|
## Get Started: [>> CLICK HERE <<](https://git.worlio.com/bonkmaykr/firestar/wiki)
|
||||||
|
|
||||||
@@ -9,12 +9,12 @@
|
|||||||
# Installation
|
# Installation
|
||||||
The latest version of Firestar will always be available from [Releases](https://git.worlio.com/bonkmaykr/firestar/releases).
|
The latest version of Firestar will always be available from [Releases](https://git.worlio.com/bonkmaykr/firestar/releases).
|
||||||
If you aren't sure which file to get:
|
If you aren't sure which file to get:
|
||||||
- **Windows:** Download the latest installer [here](https://files.worlio.com/users/bonkmaykr/tools/firestar/latest/firestar_1.2_installer_windows.exe).
|
- **Windows:** Download the latest installer [here](https://screwgravity.net/firestar/builds/stable/tetsuo/firestar_1.3_installer_winnt_x86-64.exe).
|
||||||
- **Linux:** Install one of the packages from the [Releases](https://git.worlio.com/bonkmaykr/firestar/releases) page:
|
- **Linux:** Install one of the packages from the [Releases](https://git.worlio.com/bonkmaykr/firestar/releases) page:
|
||||||
- Ubuntu, Mint, PopOS: `sudo dpkg -i firestar_ver_arch.deb` or `gdebi firestar_ver_arch.deb`
|
- Ubuntu, Mint, PopOS: `sudo dpkg -i firestar_ver_arch.deb` or `gdebi firestar_ver_arch.deb`
|
||||||
- Fedora, Mageia, OpenSUSE, AlmaLinux: `sudo rpm -i firestar-ver-arch.rpm`
|
- Fedora, Mageia, OpenSUSE, AlmaLinux: `sudo rpm -i firestar-ver-arch.rpm`
|
||||||
- Arch, EndeavourOS, CachyOS, Steam Deck: `sudo pacman -U firestar-ver-arch.pkg.tar.zst`
|
- Arch, EndeavourOS, CachyOS, Steam Deck: `sudo pacman -U firestar-ver-arch.pkg.tar.zst`
|
||||||
- **All Platforms:** Grab the [Portable ZIP](https://files.worlio.com/users/bonkmaykr/tools/firestar/latest/firestar_dekka-1.2_portable.zip), extract it, and run the JAR file.
|
- **All Platforms:** Grab the [JAR](https://screwgravity.net/firestar/builds/stable/tetsuo/firestar_1.3_portable.jar) and run it.
|
||||||
|
|
||||||
# System Requirements
|
# System Requirements
|
||||||
- Windows 8 or newer, Mac OS X 10.14 or older, any modern version of Linux/BSD
|
- Windows 8 or newer, Mac OS X 10.14 or older, any modern version of Linux/BSD
|
||||||
@@ -24,6 +24,35 @@ If you aren't sure which file to get:
|
|||||||
- **Version 1.3 and above only:** [Visual C++ 2012 libraries](http://www.microsoft.com/en-au/download/confirmation.aspx?id=30679)
|
- **Version 1.3 and above only:** [Visual C++ 2012 libraries](http://www.microsoft.com/en-au/download/confirmation.aspx?id=30679)
|
||||||
- Do NOT install Firestar directly to your PSVita's storage. Some of it's file operations do not play nice with FAT filesystems.
|
- Do NOT install Firestar directly to your PSVita's storage. Some of it's file operations do not play nice with FAT filesystems.
|
||||||
|
|
||||||
|
# Building
|
||||||
|
You are always free to copy the Firestar source code and compile the latest work-in-progress version for yourself.
|
||||||
|
Firestar uses the Gradle build system. We write our code and perform all our tests on Linux, but these same steps should apply to all major operating systems.
|
||||||
|
|
||||||
|
## With Intellij IDEA
|
||||||
|
1. Create a new project cloned from this Git repo
|
||||||
|
2. Open the run configurations editor by clicking "Default" in the top right corner and selecting "Edit Configurations".
|
||||||
|
3. Set the JDK to Java 17, the module to firestar.firestar.main and the main class to Firestar's Main class.
|
||||||
|
4. Go to Modify Options > Add before launch task, then add a Gradle "clean" task
|
||||||
|
5. Go there again and add a Gradle "build" task
|
||||||
|
6. Delete the default build task that has now appeared as step 1.
|
||||||
|
7. Save your options and click the Play button to compile and test.
|
||||||
|
|
||||||
|
## From the command line
|
||||||
|
1. Ensure you have both Git and Gradle installed on your system.
|
||||||
|
- Windows: Visit [git-scm.com](https://git-scm.com/downloads) and the [Gradle Installation Guide](https://gradle.org/install/).
|
||||||
|
- Linux/BSD: Install the `git` and `gradle` packages from your package manager. For example:
|
||||||
|
- Arch-based: `sudo pacman -Sy git gradle` (if this breaks your computer then run -Syu to rectify it)
|
||||||
|
- Debian-based: `sudo apt install git gradle`
|
||||||
|
- Mac: Figure it out! None of us on the dev team use Macs and we can't be assed to.
|
||||||
|
2. Open the terminal and clone the git repo. This will download the Firestar source code to a `firestar/` folder in your current working directory.
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://git.worlio.com/bonkmaykr/firestar.git
|
||||||
|
```
|
||||||
|
|
||||||
|
3. `cd` to `firestar/` and run `gradle build` to make a JAR or `gradle run` to test your code immediately.
|
||||||
|
- On Windows systems make sure you're running `gradlew.bat` and not the Bash script instead.
|
||||||
|
|
||||||
# FAQ
|
# FAQ
|
||||||
## Can I use this on a Vita without enso/HEN?
|
## Can I use this on a Vita without enso/HEN?
|
||||||
No. You need a modded Vita in order to use this. Hacking a Vita is super easy these days, but if you don't want to, you can always use Vita3K instead.
|
No. You need a modded Vita in order to use this. Hacking a Vita is super easy these days, but if you don't want to, you can always use Vita3K instead.
|
||||||
@@ -49,6 +78,21 @@ Firestar itself can run natively on the system, but it needs WINE in order to ha
|
|||||||
**If you are on Mac OS X you will need an older OS version that is still compatible with 32-bit applications.**
|
**If you are on Mac OS X you will need an older OS version that is still compatible with 32-bit applications.**
|
||||||
|
|
||||||
# Developer Commentary
|
# Developer Commentary
|
||||||
|
## Programmer SOP
|
||||||
|
When adding new features to Firestar, the Screw Gravity! team (loosely) follows this procedure:
|
||||||
|
1. The developer prototypes the feature, in part or in full, on a Linux system.
|
||||||
|
2. After completion, a QEMU/KVM running Windows 10 w/ VC++ 2012 libs and the latest JDK is deployed to test Firestar on.
|
||||||
|
3. Code refactoring is done to account for Windows bugs.
|
||||||
|
4. The final commit is pushed.
|
||||||
|
|
||||||
|
Try to stick to these conventions:
|
||||||
|
- Avoid allowing the user to interact with the main window (MissPiggy.java) while another menu is open that alters any data, and keep this window Always-on-top. This is usually done by passing the master JFrame as a parameter to the child and telling it to freeze the parent's JFrame until the user closes that menu.
|
||||||
|
- Keep formatting consistent and readable.
|
||||||
|
- `if` statements should have a space separating the conditions and code block.
|
||||||
|
- Use tabs instead of repeat spaces for indentation where possible and keep one indentation per layer, avoid flattening unless appropriate.
|
||||||
|
- Split up long equations and statements into new lines with an operator at the start of the new line.
|
||||||
|
- Divide really long functions into paragraph for certain major steps.
|
||||||
|
|
||||||
## Third Party Code
|
## Third Party Code
|
||||||
Firestar is built on top of the following additional software:
|
Firestar is built on top of the following additional software:
|
||||||
- *[WINE](https://www.winehq.org/), for running the below applications across platforms.
|
- *[WINE](https://www.winehq.org/), for running the below applications across platforms.
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ configurations {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation group: 'net.lingala.zip4j', name: 'zip4j', version: '2.11.5'
|
implementation group: 'net.lingala.zip4j', name: 'zip4j', version: '2.11.5'
|
||||||
implementation group: 'org.json', name: 'json', version: '20240303'
|
implementation group: 'org.json', name: 'json', version: '20240303'
|
||||||
implementation "io.github.java-diff-utils:java-diff-utils:4.12"
|
implementation group: 'io.github.java-diff-utils', name: 'java-diff-utils', version: '4.12'
|
||||||
|
implementation group: 'org.apache.commons', name: 'commons-text', version: '1.12.0'
|
||||||
|
implementation group: 'org.netbeans.external', name: 'org-apache-commons-io', version: 'RELEASE113'
|
||||||
|
|
||||||
implementation 'com.jetbrains.intellij.java:java-gui-forms-rt:203.7148.30'
|
implementation 'com.jetbrains.intellij.java:java-gui-forms-rt:203.7148.30'
|
||||||
antTask 'com.jetbrains.intellij.java:java-compiler-ant-tasks:203.7148.30'
|
antTask 'com.jetbrains.intellij.java:java-compiler-ant-tasks:203.7148.30'
|
||||||
@@ -35,6 +37,7 @@ jar {
|
|||||||
'Main-Class': 'Main'
|
'Main-Class': 'Main'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
from {
|
from {
|
||||||
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
|
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
|
||||||
}
|
}
|
||||||
|
|||||||
110
firestar/src/main/java/Beaker.form
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="Beaker">
|
||||||
|
<grid id="27dc6" binding="frameContainer" layout-manager="GridLayoutManager" row-count="2" column-count="1" 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="772" height="129"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<background color="-2271221"/>
|
||||||
|
</properties>
|
||||||
|
<border type="none"/>
|
||||||
|
<children>
|
||||||
|
<grid id="20b72" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
|
<margin top="0" left="8" bottom="0" right="8"/>
|
||||||
|
<constraints>
|
||||||
|
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||||
|
<minimum-size width="-1" height="20"/>
|
||||||
|
<preferred-size width="-1" height="80"/>
|
||||||
|
<maximum-size width="-1" height="80"/>
|
||||||
|
</grid>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<background color="-15128227"/>
|
||||||
|
<focusable value="false"/>
|
||||||
|
<font size="8"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
</properties>
|
||||||
|
<border type="none"/>
|
||||||
|
<children>
|
||||||
|
<grid id="60002" layout-manager="GridLayoutManager" row-count="1" 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>
|
||||||
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<opaque value="false"/>
|
||||||
|
</properties>
|
||||||
|
<border type="none"/>
|
||||||
|
<children>
|
||||||
|
<component id="9c218" class="javax.swing.JLabel">
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="10" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<focusable value="false"/>
|
||||||
|
<font size="10"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<text value="© 2025 Canithesis Interactive"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="4c79f" class="javax.swing.JLabel">
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="6" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<font size="10"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<text value="This program is not endorsed by Sony Computer Entertainment."/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
</children>
|
||||||
|
</grid>
|
||||||
|
<grid id="da84a" layout-manager="GridLayoutManager" row-count="1" 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>
|
||||||
|
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<opaque value="false"/>
|
||||||
|
</properties>
|
||||||
|
<border type="none"/>
|
||||||
|
<children>
|
||||||
|
<component id="c04e4" class="javax.swing.JLabel">
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<focusable value="false"/>
|
||||||
|
<font size="10"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<text value="https://screwgravity.net/firestar/"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="b7dd0" class="javax.swing.JLabel">
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="5" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<font size="10"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<text value="Developed and GNU'd by bonkmaykr. FScript thanx to Wirlaburla"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
</children>
|
||||||
|
</grid>
|
||||||
|
</children>
|
||||||
|
</grid>
|
||||||
|
<component id="19b7a" class="javax.swing.JLabel" binding="splashImg">
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||||
|
<preferred-size width="640" height="400"/>
|
||||||
|
</grid>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<text value=""/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
</children>
|
||||||
|
</grid>
|
||||||
|
</form>
|
||||||
59
firestar/src/main/java/Beaker.java
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Firestar Mod Manager
|
||||||
|
* Copyright (C) 2025 Canithesis Interactive
|
||||||
|
*
|
||||||
|
* 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 javax.imageio.ImageIO;
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
|
||||||
|
|
||||||
|
public class Beaker {
|
||||||
|
Image logo;
|
||||||
|
private JLabel splashImg;
|
||||||
|
JFrame frame = new JFrame();
|
||||||
|
JPanel frameContainer;
|
||||||
|
|
||||||
|
public Beaker() throws InterruptedException {
|
||||||
|
try {
|
||||||
|
logo = ImageIO.read(Main.class.getResourceAsStream("/splash"+(int)(Math.random()*10)+".png")).getScaledInstance(640, 400, Image.SCALE_SMOOTH);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("ERROR: Uhhhhhhhhhhh........... what?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
|
||||||
|
splashImg.setIcon(new ImageIcon(logo));splashImg.setText("");
|
||||||
|
|
||||||
|
// display window
|
||||||
|
frame.setSize(640, 450);
|
||||||
|
frame.setTitle("Firestar Mod Manager");
|
||||||
|
frame.setUndecorated(true);
|
||||||
|
frame.setResizable(false);
|
||||||
|
frame.setAlwaysOnTop(true);
|
||||||
|
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||||
|
frame.setLayout(new GridLayout());
|
||||||
|
frame.setLocationRelativeTo(null);
|
||||||
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
Thread.sleep(3000);
|
||||||
|
|
||||||
|
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||||
|
frame.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<font name="Exo 2"/>
|
<font name="Exo 2"/>
|
||||||
<foreground color="-1"/>
|
<foreground color="-1"/>
|
||||||
<text value=" If you add/remove DLC in the future, you will need to change this setting again."/>
|
<text value="Downloading a game update will automatically download its previous versions."/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
</children>
|
</children>
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
</component>
|
</component>
|
||||||
</children>
|
</children>
|
||||||
</grid>
|
</grid>
|
||||||
<grid id="1000f" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
<grid id="1000f" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
<margin top="0" left="0" bottom="0" right="0"/>
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
@@ -120,52 +120,219 @@
|
|||||||
</properties>
|
</properties>
|
||||||
<border type="none"/>
|
<border type="none"/>
|
||||||
<children>
|
<children>
|
||||||
<component id="ec9c0" class="javax.swing.JCheckBox" binding="patchCheck">
|
|
||||||
<constraints>
|
|
||||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="10" fill="0" indent="0" use-parent-layout="false"/>
|
|
||||||
</constraints>
|
|
||||||
<properties>
|
|
||||||
<background color="-15128227"/>
|
|
||||||
<font name="Exo 2"/>
|
|
||||||
<foreground color="-1"/>
|
|
||||||
<horizontalTextPosition value="11"/>
|
|
||||||
<text value="Updates"/>
|
|
||||||
</properties>
|
|
||||||
</component>
|
|
||||||
<component id="a6e9" class="javax.swing.JCheckBox" binding="baseCheck">
|
|
||||||
<constraints>
|
|
||||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="6" fill="0" indent="0" use-parent-layout="false"/>
|
|
||||||
</constraints>
|
|
||||||
<properties>
|
|
||||||
<background color="-15128227"/>
|
|
||||||
<font name="Exo 2"/>
|
|
||||||
<foreground color="-1"/>
|
|
||||||
<horizontalTextPosition value="10"/>
|
|
||||||
<text value="Base game"/>
|
|
||||||
</properties>
|
|
||||||
</component>
|
|
||||||
<component id="f3723" class="javax.swing.JCheckBox" binding="hdCheck">
|
<component id="f3723" class="javax.swing.JCheckBox" binding="hdCheck">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="5" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="5" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<background color="-15128227"/>
|
<background color="-15128227"/>
|
||||||
|
<focusPainted value="false"/>
|
||||||
<font name="Exo 2"/>
|
<font name="Exo 2"/>
|
||||||
<foreground color="-1"/>
|
<foreground color="-1"/>
|
||||||
<horizontalTextPosition value="10"/>
|
<horizontalTextPosition value="10"/>
|
||||||
|
<opaque value="false"/>
|
||||||
<text value="HD Add-On Pack"/>
|
<text value="HD Add-On Pack"/>
|
||||||
|
<verticalTextPosition value="0"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="5ed0c" class="javax.swing.JCheckBox" binding="furyCheck">
|
<component id="5ed0c" class="javax.swing.JCheckBox" binding="furyCheck">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<background color="-15128227"/>
|
||||||
|
<focusPainted value="false"/>
|
||||||
|
<font name="Exo 2"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<horizontalTextPosition value="11"/>
|
||||||
|
<opaque value="false"/>
|
||||||
|
<selected value="false"/>
|
||||||
|
<text value="Fury Add-On Pack"/>
|
||||||
|
<verticalTextPosition value="0"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<grid id="afeb1" layout-manager="GridLayoutManager" row-count="3" 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>
|
||||||
|
<grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="1" anchor="2" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<background color="-15128227"/>
|
||||||
|
<opaque value="false"/>
|
||||||
|
</properties>
|
||||||
|
<border type="none"/>
|
||||||
|
<children>
|
||||||
|
<component id="6337e" class="javax.swing.JRadioButton" binding="baseCheck">
|
||||||
|
<constraints>
|
||||||
|
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="10" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<background color="-15128227"/>
|
||||||
|
<focusPainted value="false"/>
|
||||||
|
<font name="Exo 2"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<horizontalAlignment value="0"/>
|
||||||
|
<horizontalTextPosition value="11"/>
|
||||||
|
<opaque value="false"/>
|
||||||
|
<text value="Base Game"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="5c733" class="javax.swing.JRadioButton" binding="patchCheck2">
|
||||||
|
<constraints>
|
||||||
|
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="2" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<background color="-15128227"/>
|
||||||
|
<focusPainted value="false"/>
|
||||||
|
<font name="Exo 2"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<label value="v1.04 (Latest)"/>
|
||||||
|
<opaque value="false"/>
|
||||||
|
<selected value="true"/>
|
||||||
|
<text value="v1.04 (Latest)"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="f9b10" class="javax.swing.JRadioButton" binding="patchCheck1">
|
||||||
|
<constraints>
|
||||||
|
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="2" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<background color="-15128227"/>
|
||||||
|
<focusPainted value="false"/>
|
||||||
|
<font name="Exo 2"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<opaque value="false"/>
|
||||||
|
<text value="v1.01+"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="826d4" class="javax.swing.JLabel">
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<background color="-15128227"/>
|
<background color="-15128227"/>
|
||||||
<font name="Exo 2"/>
|
<font name="Exo 2"/>
|
||||||
<foreground color="-1"/>
|
<foreground color="-1"/>
|
||||||
|
<opaque value="false"/>
|
||||||
|
<text value="Select Game Version:"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="26170" class="javax.swing.JCheckBox" binding="skipBaseCheck">
|
||||||
|
<constraints>
|
||||||
|
<grid row="2" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<background color="-15128227"/>
|
||||||
|
<enabled value="false"/>
|
||||||
|
<focusPainted value="false"/>
|
||||||
|
<font name="Exo 2"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<label value="Don't redownload existing core game files"/>
|
||||||
|
<text value="Don't redownload existing core game files"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
</children>
|
||||||
|
</grid>
|
||||||
|
<component id="45b94" class="javax.swing.JLabel">
|
||||||
|
<constraints>
|
||||||
|
<grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="2" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<background color="-15128227"/>
|
||||||
|
<font name="Exo 2"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<opaque value="false"/>
|
||||||
|
<text value="Select DLC Packs:"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<grid id="d53a4" binding="installedList" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="0" row-span="3" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<focusable value="false"/>
|
||||||
|
<opaque value="false"/>
|
||||||
|
</properties>
|
||||||
|
<border type="line" title="Installed Packs" title-justification="2" title-position="1">
|
||||||
|
<font name="Exo 2"/>
|
||||||
|
<title-color color="-1"/>
|
||||||
|
<color color="-1"/>
|
||||||
|
</border>
|
||||||
|
<children>
|
||||||
|
<grid id="e1f58" binding="installedListMargin" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
|
<margin top="4" left="16" bottom="4" right="16"/>
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<focusable value="false"/>
|
||||||
|
<opaque value="false"/>
|
||||||
|
</properties>
|
||||||
|
<border type="none"/>
|
||||||
|
<children>
|
||||||
|
<component id="74ba9" class="javax.swing.JLabel" binding="ipcBase">
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<font name="Exo 2"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<horizontalAlignment value="2"/>
|
||||||
<horizontalTextPosition value="11"/>
|
<horizontalTextPosition value="11"/>
|
||||||
<selected value="false"/>
|
<icon value="lightNegative.png"/>
|
||||||
|
<text value="Base Game"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="afce0" class="javax.swing.JLabel" binding="ipcPatch1">
|
||||||
|
<constraints>
|
||||||
|
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<font name="Exo 2"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<horizontalAlignment value="2"/>
|
||||||
|
<horizontalTextPosition value="11"/>
|
||||||
|
<icon value="lightNegative.png"/>
|
||||||
|
<text value="Update v1.01"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="209d6" class="javax.swing.JLabel" binding="ipcPatch2">
|
||||||
|
<constraints>
|
||||||
|
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<font name="Exo 2"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<horizontalAlignment value="2"/>
|
||||||
|
<horizontalTextPosition value="11"/>
|
||||||
|
<icon value="lightNegative.png"/>
|
||||||
|
<text value="Update v1.04"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="dbb59" class="javax.swing.JLabel" binding="ipcDlcHD">
|
||||||
|
<constraints>
|
||||||
|
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<font name="Exo 2"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<horizontalAlignment value="2"/>
|
||||||
|
<horizontalTextPosition value="11"/>
|
||||||
|
<icon value="lightNegative.png"/>
|
||||||
|
<text value="HD Add-On Pack"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
|
<component id="c1b3f" class="javax.swing.JLabel" binding="ipcDlcFury">
|
||||||
|
<constraints>
|
||||||
|
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<font name="Exo 2"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<horizontalAlignment value="2"/>
|
||||||
|
<horizontalTextPosition value="11"/>
|
||||||
|
<icon value="lightNegative.png"/>
|
||||||
<text value="Fury Add-On Pack"/>
|
<text value="Fury Add-On Pack"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
@@ -175,4 +342,8 @@
|
|||||||
</grid>
|
</grid>
|
||||||
</children>
|
</children>
|
||||||
</grid>
|
</grid>
|
||||||
|
</children>
|
||||||
|
</grid>
|
||||||
|
</children>
|
||||||
|
</grid>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -30,10 +30,19 @@ public class Bert implements ActionListener {
|
|||||||
private JPanel frameContainer;
|
private JPanel frameContainer;
|
||||||
private JButton cancelbtn;
|
private JButton cancelbtn;
|
||||||
private JButton downloadbtn;
|
private JButton downloadbtn;
|
||||||
private JCheckBox patchCheck;
|
private JRadioButton baseCheck;
|
||||||
private JCheckBox baseCheck;
|
private JRadioButton patchCheck1;
|
||||||
|
private JRadioButton patchCheck2;
|
||||||
private JCheckBox hdCheck;
|
private JCheckBox hdCheck;
|
||||||
private JCheckBox furyCheck;
|
private JCheckBox furyCheck;
|
||||||
|
private JCheckBox skipBaseCheck;
|
||||||
|
private JPanel installedList;
|
||||||
|
private JLabel ipcBase;
|
||||||
|
private JLabel ipcPatch1;
|
||||||
|
private JLabel ipcPatch2;
|
||||||
|
private JLabel ipcDlcHD;
|
||||||
|
private JLabel ipcDlcFury;
|
||||||
|
private JPanel installedListMargin;
|
||||||
private ButtonGroup radios = new ButtonGroup();
|
private ButtonGroup radios = new ButtonGroup();
|
||||||
|
|
||||||
private JFrame invoker;
|
private JFrame invoker;
|
||||||
@@ -54,8 +63,17 @@ public class Bert implements ActionListener {
|
|||||||
frame.setLocationRelativeTo(parent);
|
frame.setLocationRelativeTo(parent);
|
||||||
frame.setAlwaysOnTop(true);
|
frame.setAlwaysOnTop(true);
|
||||||
|
|
||||||
|
radios.add(baseCheck);
|
||||||
|
radios.add(patchCheck1);
|
||||||
|
radios.add(patchCheck2);
|
||||||
|
|
||||||
cancelbtn.addActionListener(this);
|
cancelbtn.addActionListener(this);
|
||||||
downloadbtn.addActionListener(this);
|
downloadbtn.addActionListener(this);
|
||||||
|
baseCheck.addActionListener(this);
|
||||||
|
patchCheck1.addActionListener(this);
|
||||||
|
patchCheck2.addActionListener(this);
|
||||||
|
|
||||||
|
refreshChecklist();
|
||||||
|
|
||||||
frame.setIconImage(Main.windowIcon);
|
frame.setIconImage(Main.windowIcon);
|
||||||
|
|
||||||
@@ -74,6 +92,9 @@ public class Bert implements ActionListener {
|
|||||||
invoker.setEnabled(true);
|
invoker.setEnabled(true);
|
||||||
frame.dispose();
|
frame.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (new File(Main.inpath + "data2.psarc").exists())
|
||||||
|
skipBaseCheck.setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean reportWhenDownloaded(WilkinsCoffee setup) {
|
public boolean reportWhenDownloaded(WilkinsCoffee setup) {
|
||||||
@@ -87,34 +108,80 @@ public class Bert implements ActionListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent actionEvent) {
|
public void actionPerformed(ActionEvent actionEvent) {
|
||||||
|
if (actionEvent.getSource() == baseCheck)
|
||||||
|
skipBaseCheck.setEnabled(new File(Main.inpath + "data.psarc").exists()); else
|
||||||
|
if (actionEvent.getSource() == patchCheck1)
|
||||||
|
skipBaseCheck.setEnabled(new File(Main.inpath + "data1.psarc").exists()); else
|
||||||
|
if (actionEvent.getSource() == patchCheck2)
|
||||||
|
skipBaseCheck.setEnabled(new File(Main.inpath + "data2.psarc").exists()); else
|
||||||
if (actionEvent.getSource() == cancelbtn) {
|
if (actionEvent.getSource() == cancelbtn) {
|
||||||
invoker.setEnabled(true);
|
invoker.setEnabled(true);
|
||||||
frame.dispose();
|
frame.dispose();
|
||||||
} else if (actionEvent.getSource() == downloadbtn) {
|
} else if (actionEvent.getSource() == downloadbtn) {
|
||||||
ArrayList<Main.ArcTarget> arcs = new ArrayList<Main.ArcTarget>();
|
ArrayList<Main.ArcTarget> arcs = new ArrayList<Main.ArcTarget>();
|
||||||
ArrayList<Main.ArcKey> keys = new ArrayList<Main.ArcKey>();
|
ArrayList<Main.ArcKey> keys = new ArrayList<Main.ArcKey>();
|
||||||
if (baseCheck.isSelected()) {
|
|
||||||
|
// Always download predecessors to ensure no missing files
|
||||||
|
// Probably not necessary since I will be adding selective extraction to Gonzo,
|
||||||
|
// and throw errors when a lower PSARC doesn't exist, but there's no real reason not to.
|
||||||
|
//
|
||||||
|
// Of course, to avoid additional download times, we should probably
|
||||||
|
// avoid adding to the download list if a file already exists, unless explicitly
|
||||||
|
// selected (the exact radio button). The user can redownload one at a time
|
||||||
|
// but Firestar will not overwrite existing PSARCs otherwise.
|
||||||
|
if (baseCheck.isSelected()) { // I have the base game
|
||||||
|
if (!skipBaseCheck.isSelected() || !new File(Main.inpath + "data.psarc").exists()) {
|
||||||
arcs.add(Main.ArcTarget.BASE);
|
arcs.add(Main.ArcTarget.BASE);
|
||||||
keys.add(Main.ArcKey.BASE);
|
keys.add(Main.ArcKey.BASE);
|
||||||
System.out.println("Begin download of data (Game version 1.0)");
|
System.out.println("Queued download of data (Game version 1.0)");
|
||||||
}
|
}
|
||||||
if (patchCheck.isSelected()) {
|
}
|
||||||
|
if (patchCheck1.isSelected()) { // I updated it once after it came out and then didn't turn my vita on for thousands of years
|
||||||
|
if (!new File(Main.inpath + "data.psarc").exists()) {
|
||||||
|
arcs.add(Main.ArcTarget.BASE);
|
||||||
|
keys.add(Main.ArcKey.BASE);
|
||||||
|
System.out.println("Queued download of data (Game version 1.0)");
|
||||||
|
}
|
||||||
|
if (!skipBaseCheck.isSelected() || !new File(Main.inpath + "data1.psarc").exists()) {
|
||||||
|
arcs.add(Main.ArcTarget.FIRST);
|
||||||
|
keys.add(Main.ArcKey.FIRST);
|
||||||
|
System.out.println("Queued download of data1 (Game version 1.01)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (patchCheck2.isSelected()) { // I'm a normal fucking person
|
||||||
|
if (!new File(Main.inpath + "data.psarc").exists()) {
|
||||||
|
arcs.add(Main.ArcTarget.BASE);
|
||||||
|
keys.add(Main.ArcKey.BASE);
|
||||||
|
System.out.println("Queued download of data (Game version 1.0)");
|
||||||
|
}
|
||||||
|
if (!new File(Main.inpath + "data1.psarc").exists()) {
|
||||||
|
arcs.add(Main.ArcTarget.FIRST);
|
||||||
|
keys.add(Main.ArcKey.FIRST);
|
||||||
|
System.out.println("Queued download of data1 (Game version 1.01)");
|
||||||
|
}
|
||||||
|
if (!skipBaseCheck.isSelected() || !new File(Main.inpath + "data2.psarc").exists()) {
|
||||||
arcs.add(Main.ArcTarget.LATEST);
|
arcs.add(Main.ArcTarget.LATEST);
|
||||||
keys.add(Main.ArcKey.LATEST);
|
keys.add(Main.ArcKey.LATEST);
|
||||||
System.out.println("Begin download of data2 (Game version 1.04)");
|
System.out.println("Queued download of data2 (Game version 1.04)");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DLC are installed arbitrarily, separate of the game, and can remain as checkboxes with the old logic.
|
||||||
|
// Likewise, the old overwrite policy applies. If the user selects these, it WILL download with no question.
|
||||||
if (hdCheck.isSelected()) {
|
if (hdCheck.isSelected()) {
|
||||||
arcs.add(Main.ArcTarget.ADDON_HD);
|
arcs.add(Main.ArcTarget.ADDON_HD);
|
||||||
keys.add(Main.ArcKey.ADDON_HD);
|
keys.add(Main.ArcKey.ADDON_HD);
|
||||||
System.out.println("Begin download of dlc1 (HD DLC)");
|
System.out.println("Queued download of dlc1 (HD DLC)");
|
||||||
}
|
}
|
||||||
if (furyCheck.isSelected()) {
|
if (furyCheck.isSelected()) {
|
||||||
arcs.add(Main.ArcTarget.ADDON_HD_FURY);
|
arcs.add(Main.ArcTarget.ADDON_HD_FURY);
|
||||||
keys.add(Main.ArcKey.ADDON_HD_FURY);
|
keys.add(Main.ArcKey.ADDON_HD_FURY);
|
||||||
System.out.println("Begin download of dlc2 (Fury DLC)");
|
System.out.println("Queued download of dlc2 (Fury DLC)");
|
||||||
}
|
}
|
||||||
if (arcs.isEmpty()) {
|
if (arcs.isEmpty()) {
|
||||||
|
frame.setVisible(false);
|
||||||
JOptionPane.showMessageDialog(invoker, "Select one or more asset packs.", "Error", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(invoker, "Select one or more asset packs.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
frame.setVisible(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,9 +199,13 @@ public class Bert implements ActionListener {
|
|||||||
key = Main.ArcKey.BASE.toString();
|
key = Main.ArcKey.BASE.toString();
|
||||||
arcname = "Base game";
|
arcname = "Base game";
|
||||||
break;
|
break;
|
||||||
|
case FIRST :
|
||||||
|
key = Main.ArcKey.FIRST.toString();
|
||||||
|
arcname = "Update 1.01";
|
||||||
|
break;
|
||||||
case LATEST :
|
case LATEST :
|
||||||
key = Main.ArcKey.LATEST.toString();
|
key = Main.ArcKey.LATEST.toString();
|
||||||
arcname = "Updates";
|
arcname = "Update 1.04";
|
||||||
break;
|
break;
|
||||||
case ADDON_HD :
|
case ADDON_HD :
|
||||||
key = Main.ArcKey.ADDON_HD.toString();
|
key = Main.ArcKey.ADDON_HD.toString();
|
||||||
@@ -172,7 +243,7 @@ public class Bert implements ActionListener {
|
|||||||
Fozzie popup = new Fozzie();
|
Fozzie popup = new Fozzie();
|
||||||
popup.displayTextOnly("Extracting " + arcname + "...", "Extracting");
|
popup.displayTextOnly("Extracting " + arcname + "...", "Extracting");
|
||||||
try {
|
try {
|
||||||
Process p = Main.exec(new String[]{"pkg2zip.exe", "-x", "asset.pkg", key.toString()}, Main.inpath);
|
Process p = Main.exec(new String[]{Main.inpath + "pkg2zip.exe", "-x", "asset.pkg", key.toString()}, Main.inpath);
|
||||||
InputStream debugin = new BufferedInputStream(p.getInputStream());
|
InputStream debugin = new BufferedInputStream(p.getInputStream());
|
||||||
OutputStream debugout = new BufferedOutputStream(System.out);
|
OutputStream debugout = new BufferedOutputStream(System.out);
|
||||||
int c;
|
int c;
|
||||||
@@ -200,6 +271,9 @@ public class Bert implements ActionListener {
|
|||||||
if (type == Main.ArcTarget.BASE) {
|
if (type == Main.ArcTarget.BASE) {
|
||||||
extracted = "app/PCSA00015";
|
extracted = "app/PCSA00015";
|
||||||
name = "data.psarc";
|
name = "data.psarc";
|
||||||
|
} else if (type == Main.ArcTarget.FIRST) {
|
||||||
|
extracted = "patch/PCSA00015";
|
||||||
|
name = "data1.psarc";
|
||||||
} else if (type == Main.ArcTarget.LATEST) {
|
} else if (type == Main.ArcTarget.LATEST) {
|
||||||
extracted = "patch/PCSA00015";
|
extracted = "patch/PCSA00015";
|
||||||
name = "data2.psarc";
|
name = "data2.psarc";
|
||||||
@@ -226,7 +300,7 @@ public class Bert implements ActionListener {
|
|||||||
popup.setText("<html>Decrypting protected PFS:<br/>" + extracted + "</html>", "Decrypting");
|
popup.setText("<html>Decrypting protected PFS:<br/>" + extracted + "</html>", "Decrypting");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Process p = Main.exec(new String[]{"psvpfsparser.exe", "-i", extracted, "-o", "./temp/", "-z", key.toString(), "-f", "cma.henkaku.xyz"}, Main.inpath);
|
Process p = Main.exec(new String[]{Main.inpath + "psvpfsparser.exe", "-i", extracted, "-o", "./temp/", "-z", key.toString(), "-f", "cma.henkaku.xyz"}, Main.inpath);
|
||||||
InputStream debugin = new BufferedInputStream(p.getInputStream());
|
InputStream debugin = new BufferedInputStream(p.getInputStream());
|
||||||
OutputStream debugout = new BufferedOutputStream(System.out);
|
OutputStream debugout = new BufferedOutputStream(System.out);
|
||||||
int c;
|
int c;
|
||||||
@@ -276,4 +350,20 @@ public class Bert implements ActionListener {
|
|||||||
downloaderPopupThread.start();
|
downloaderPopupThread.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void refreshChecklist() {
|
||||||
|
ImageIcon positive = new ImageIcon(Main.class.getResource("/lightPositive.png"));
|
||||||
|
ImageIcon negative = new ImageIcon(Main.class.getResource("/lightNegative.png"));
|
||||||
|
|
||||||
|
if(new File(Main.inpath + "data.psarc").exists())
|
||||||
|
ipcBase.setIcon(positive); else ipcBase.setIcon(negative);
|
||||||
|
if(new File(Main.inpath + "data1.psarc").exists())
|
||||||
|
ipcPatch1.setIcon(positive); else ipcPatch1.setIcon(negative);
|
||||||
|
if(new File(Main.inpath + "data2.psarc").exists())
|
||||||
|
ipcPatch2.setIcon(positive); else ipcPatch2.setIcon(negative);
|
||||||
|
if(new File(Main.inpath + "dlc1.psarc").exists())
|
||||||
|
ipcDlcHD.setIcon(positive); else ipcDlcHD.setIcon(negative);
|
||||||
|
if(new File(Main.inpath + "dlc2.psarc").exists())
|
||||||
|
ipcDlcFury.setIcon(positive); else ipcDlcFury.setIcon(negative);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,12 +163,15 @@ public class Clifford implements ActionListener {
|
|||||||
JOptionPane.showMessageDialog(frame, "Mod name cannot be empty.", "Error", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(frame, "Mod name cannot be empty.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
container.put("version", mod.version);
|
container.put("version", mod.version);
|
||||||
container.put("friendlyName", mod.friendlyName);
|
container.put("friendlyName", mod.friendlyName);
|
||||||
container.put("author", mod.author);
|
container.put("author", mod.author);
|
||||||
container.put("description", mod.description);
|
container.put("description", mod.description);
|
||||||
container.put("loaderversion", mod.loaderversion);
|
container.put("loaderversion", mod.loaderversion);
|
||||||
container.put("game", mod.game);
|
container.put("game", mod.game);
|
||||||
|
if (!mod.requires.isEmpty()) container.put("requires", mod.requires);
|
||||||
|
if (!mod.extracts.isEmpty()) container.put("extracts", mod.extracts);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new ZipFile(System.getProperty("user.home") + "/.firestar/mods/" + mod.path.trim()).setComment(container.toString());
|
new ZipFile(System.getProperty("user.home") + "/.firestar/mods/" + mod.path.trim()).setComment(container.toString());
|
||||||
@@ -196,7 +199,9 @@ public class Clifford implements ActionListener {
|
|||||||
JFileChooser fileChooser = new JFileChooser();
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
fileChooser.setFileFilter(new FileNameExtensionFilter("Firestar Mod Package", "fstar"));
|
fileChooser.setFileFilter(new FileNameExtensionFilter("Firestar Mod Package", "fstar"));
|
||||||
if (fileChooser.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
|
if (fileChooser.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
|
||||||
ZipFile zip = new ZipFile(fileChooser.getSelectedFile());
|
File modFile = fileChooser.getSelectedFile();
|
||||||
|
if (!modFile.getName().endsWith(".fstar")) modFile = new File(modFile.toString() + ".fstar");
|
||||||
|
ZipFile zip = new ZipFile(modFile);
|
||||||
boolean hasScript = false;
|
boolean hasScript = false;
|
||||||
try {
|
try {
|
||||||
zip.addFolder(new File(directory.getAbsolutePath() + "/data"));
|
zip.addFolder(new File(directory.getAbsolutePath() + "/data"));
|
||||||
@@ -211,21 +216,39 @@ public class Clifford implements ActionListener {
|
|||||||
hasScript = true;
|
hasScript = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArrayList<String> requires = new ArrayList<>();
|
||||||
|
ArrayList<String> extracts = new ArrayList<>();
|
||||||
|
if (isSoundtrack) {
|
||||||
|
requires.add("data2.psarc");
|
||||||
|
extracts.add("data/plugins/music/Definition.xml");
|
||||||
|
extracts.add("data/plugins/languages/american/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/danish/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/dutch/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/english/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/finnish/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/french/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/german/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/italian/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/japanese/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/norwegian/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/polish/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/portuguese/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/russian/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/spanish/entries.xml");
|
||||||
|
extracts.add("data/plugins/languages/swedish/entries.xml");
|
||||||
|
}
|
||||||
|
|
||||||
JSONObject container = new JSONObject();
|
JSONObject container = new JSONObject();
|
||||||
container.put("version", Integer.parseInt(fVersion.getText()));
|
container.put("version", Integer.parseInt(fVersion.getText()));
|
||||||
container.put("friendlyName", fName.getText());
|
container.put("friendlyName", fName.getText());
|
||||||
container.put("author", fAuthor.getText());
|
container.put("author", fAuthor.getText());
|
||||||
container.put("description", fDescription.getText());
|
container.put("description", fDescription.getText());
|
||||||
|
if (!requires.isEmpty()) container.put("requires", requires);
|
||||||
|
if (!extracts.isEmpty()) container.put("extracts", extracts);
|
||||||
// todo later versions: handle logic for setting this depending on the fscript version too.
|
// todo later versions: handle logic for setting this depending on the fscript version too.
|
||||||
// firestar 1.3 can't generate any version other than v1 so this is not necessary right now, but will become necessary when fscript features are added.
|
// firestar 1.3 can't generate any version other than v1 so this is not necessary right now, but will become necessary when fscript features are added.
|
||||||
if (hasScript) {
|
if (hasScript) {
|
||||||
container.put("loaderversion", 1);
|
container.put("loaderversion", 1);
|
||||||
if (isSoundtrack) {
|
|
||||||
ArrayList<boolean[]> requiresTemp = new ArrayList<>();
|
|
||||||
requiresTemp.add(new boolean[]{true, false, false, false});
|
|
||||||
requiresTemp.add(new boolean[]{false, true, false, false});
|
|
||||||
container.put("requires", requiresTemp); // Pull localization files for patching.
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
container.put("loaderversion", 0);
|
container.put("loaderversion", 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class Ernie implements ActionListener {
|
|||||||
|
|
||||||
private JFrame parent;
|
private JFrame parent;
|
||||||
|
|
||||||
public Ernie(JFrame parent) {
|
public Ernie(JFrame parent, boolean isManual) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
frame.setIconImage(Main.windowIcon);
|
frame.setIconImage(Main.windowIcon);
|
||||||
byte[] urlraw = getFile(gitapi+"/releases?draft=false&pre-release=false");
|
byte[] urlraw = getFile(gitapi+"/releases?draft=false&pre-release=false");
|
||||||
@@ -72,7 +72,9 @@ public class Ernie implements ActionListener {
|
|||||||
try {
|
try {
|
||||||
JSONArray releases = new JSONArray(new String(urlraw, Charset.forName("utf-8")));
|
JSONArray releases = new JSONArray(new String(urlraw, Charset.forName("utf-8")));
|
||||||
System.out.println("Updater: latest release is " + ((JSONObject)releases.get(0)).get("tag_name"));
|
System.out.println("Updater: latest release is " + ((JSONObject)releases.get(0)).get("tag_name"));
|
||||||
if (releases.length() >= 1 && !((JSONObject)releases.get(0)).get("tag_name").equals(Main.vtag)) {
|
if (releases.length() >= 1
|
||||||
|
&& (!Main.isNightly && (!((JSONObject)releases.get(0)).get("tag_name").equals(Main.vtag))
|
||||||
|
|| (Main.isNightly && !((JSONObject)releases.get(0)).get("tag_name").equals(Main.vtagPrevious)))) {
|
||||||
System.out.println("Updater: Your version is out of date.");
|
System.out.println("Updater: Your version is out of date.");
|
||||||
frame.add(frameContainer);
|
frame.add(frameContainer);
|
||||||
notnowbtn.addActionListener(this);
|
notnowbtn.addActionListener(this);
|
||||||
@@ -97,10 +99,11 @@ public class Ernie implements ActionListener {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
} else { System.out.println("Updater: No updates."); }
|
} else {
|
||||||
} catch (IOException ex) {
|
System.out.println("Updater: No updates.");
|
||||||
Logger.getLogger(Ernie.class.getName()).log(Level.SEVERE, null, ex);
|
if (isManual) {JOptionPane.showMessageDialog(frame, "There are no updates at this time.", "Check for Updates", JOptionPane.INFORMATION_MESSAGE);}
|
||||||
} catch (JSONException ex) {
|
}
|
||||||
|
} catch (IOException | JSONException ex) {
|
||||||
Logger.getLogger(Ernie.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(Ernie.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
public class FirescriptFormatException extends Exception {
|
public class FirescriptFormatException extends Exception {
|
||||||
public FirescriptFormatException() {
|
public FirescriptFormatException() {
|
||||||
super();
|
super();
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class Fozzie {
|
|||||||
frame.setIconImage(Main.windowIcon);
|
frame.setIconImage(Main.windowIcon);
|
||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
|
|
||||||
label.setText("Downloading \"" + dname + "\"");
|
label.setText("Downloading " + dname);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
URL fileURL = new URL(url);
|
URL fileURL = new URL(url);
|
||||||
|
|||||||
@@ -16,28 +16,21 @@
|
|||||||
* along with this program. If not, see https://www.gnu.org/licenses/.
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import com.github.difflib.DiffUtils;
|
|
||||||
import com.github.difflib.UnifiedDiffUtils;
|
|
||||||
import com.github.difflib.patch.Patch;
|
|
||||||
import net.lingala.zip4j.ZipFile;
|
import net.lingala.zip4j.ZipFile;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.TitledBorder;
|
import javax.swing.border.TitledBorder;
|
||||||
|
import javax.swing.text.DefaultCaret;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.DirectoryStream;
|
import java.nio.file.*;
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class Gonzo {
|
public class Gonzo {
|
||||||
JFrame frame = new JFrame();
|
JFrame frame = new JFrame();
|
||||||
@@ -83,6 +76,9 @@ public class Gonzo {
|
|||||||
frame.setAlwaysOnTop(true);
|
frame.setAlwaysOnTop(true);
|
||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
|
|
||||||
|
DefaultCaret caret = (DefaultCaret) consoleDisplay.getCaret();
|
||||||
|
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
|
||||||
|
|
||||||
File psarcHandle = new File(Main.inpath + "data.psarc");
|
File psarcHandle = new File(Main.inpath + "data.psarc");
|
||||||
data0 = psarcHandle.isFile();
|
data0 = psarcHandle.isFile();
|
||||||
psarcHandle = new File(Main.inpath + "data1.psarc");
|
psarcHandle = new File(Main.inpath + "data1.psarc");
|
||||||
@@ -110,24 +106,47 @@ public class Gonzo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void CompatibilityRoutine() {
|
private void CompatibilityRoutine() {
|
||||||
|
// cleanup any failed deploys to avoid scripts running when they are not supposed to be
|
||||||
|
Main.deleteDir(new File(System.getProperty("user.home") + "/.firestar/temp/"));
|
||||||
|
|
||||||
// create temporary working area for asset dump
|
// create temporary working area for asset dump
|
||||||
new File(System.getProperty("user.home") + "/.firestar/temp/").mkdirs();
|
new File(System.getProperty("user.home") + "/.firestar/temp/").mkdirs();
|
||||||
|
new File(System.getProperty("user.home") + "/.firestar/temparcs/").mkdirs();
|
||||||
|
|
||||||
|
// Work from bottom to top, mods on top always overwrite the ones on the bottom.
|
||||||
|
List<Main.Mod> modsFlipped = new ArrayList<>(Main.Mods);
|
||||||
|
Collections.reverse(modsFlipped);
|
||||||
|
|
||||||
// decide which files to dump
|
// decide which files to dump
|
||||||
List<String> dumpThese = new ArrayList<String>();
|
List<String> dumpThese = new ArrayList<String>();
|
||||||
if (data0) {dumpThese.add("data.psarc");oArcTarget = "data.psarc";}
|
for (Main.Mod m : modsFlipped) {
|
||||||
if (data1) {dumpThese.add("data1.psarc");oArcTarget = "data1.psarc";}
|
if (m.enabled) {
|
||||||
if (data2) {dumpThese.add("data2.psarc");oArcTarget = "data2.psarc";}
|
System.out.println(m.friendlyName + " : " + m.requires.toString() + " : " + m.extracts.toString());
|
||||||
if (dlc1) {dumpThese.add("dlc1.psarc");oArcTarget = "dlc1.psarc";}
|
for (String r : m.requires) if (!dumpThese.contains(r)) dumpThese.add(r);
|
||||||
if (dlc2) {dumpThese.add("dlc2.psarc");oArcTarget = "dlc2.psarc";}
|
}
|
||||||
|
}
|
||||||
|
if (data0) oArcTarget = "data.psarc";
|
||||||
|
if (data1) oArcTarget = "data1.psarc";
|
||||||
|
if (data2) oArcTarget = "data2.psarc";
|
||||||
|
if (dlc1) oArcTarget = "dlc1.psarc";
|
||||||
|
if (dlc2) oArcTarget = "dlc2.psarc";
|
||||||
|
dumpThese.remove(oArcTarget); dumpThese.add(oArcTarget); // Always dump the base game last. TODO should we allow mods to specify otherwise??
|
||||||
|
System.out.println("List of files to dump: " + dumpThese);
|
||||||
|
|
||||||
// dump all assets to working area
|
// dump all assets to working area
|
||||||
for (String s : dumpThese) {
|
for (String s : dumpThese) {
|
||||||
try {
|
try {
|
||||||
|
if (!(new File(Main.inpath + s).exists()))
|
||||||
|
throw new IOException("A mod requested access to the archive \"" + s + "\" but it doesn't exist!");
|
||||||
|
|
||||||
System.out.println("Firestar is extracting " + s);
|
System.out.println("Firestar is extracting " + s);
|
||||||
consoleDisplay.append("Firestar is extracting " + s + "\n");
|
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;
|
||||||
Process p = Main.exec(new String[]{"../psp2psarc.exe", "extract", "-y", "../"+s}, System.getProperty("user.home") + "/.firestar/temp/");
|
if (s.equals(oArcTarget)) p = Main.exec(new String[]{Main.inpath + "psp2psarc.exe", "extract", "-y", "../"+s}, System.getProperty("user.home") + "/.firestar/temp/");
|
||||||
|
else {
|
||||||
|
new File(System.getProperty("user.home") + "/.firestar/temparcs/" + s + "/").mkdirs();
|
||||||
|
p = Main.exec(new String[]{Main.inpath + "psp2psarc.exe", "extract", "-y", "../../"+s}, System.getProperty("user.home") + "/.firestar/temparcs/" + s + "/");
|
||||||
|
}
|
||||||
final Thread ioThread = new Thread() {
|
final Thread ioThread = new Thread() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -161,21 +180,50 @@ 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 : modsFlipped) {
|
||||||
if (m.enabled) {
|
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");
|
||||||
new ZipFile(System.getProperty("user.home") + "/.firestar/mods/" + m.path).extractAll(System.getProperty("user.home") + "/.firestar/temp/");
|
new ZipFile(System.getProperty("user.home") + "/.firestar/mods/" + m.path).extractAll(System.getProperty("user.home") + "/.firestar/temp/");
|
||||||
|
|
||||||
|
if (!m.requires.isEmpty() && !m.extracts.isEmpty()) {
|
||||||
|
for (String r : m.requires) {
|
||||||
|
for (String e : m.extracts) {
|
||||||
|
File f = new File(Main.inpath + "temparcs/" + r + "/" + e);
|
||||||
|
File f2 = new File(Main.inpath + "temp/" + e);
|
||||||
|
if (f2.exists()) {
|
||||||
|
System.out.println("File \"" + e + "\" already exists in master PSARC. Ignoring.");
|
||||||
|
consoleDisplay.append("File \"" + e + "\" already exists in master PSARC. Ignoring." + "\n");
|
||||||
|
}
|
||||||
|
else if (f.exists()) {
|
||||||
|
Path src = Paths.get(Main.inpath + "temparcs/" + r + "/" + e);
|
||||||
|
Path dest = Paths.get(Main.inpath + "temp/" + e);
|
||||||
|
System.out.println("Copying extra file " + e + " from " + r);
|
||||||
|
consoleDisplay.append("Copying extra file " + e + " from " + r + "\n");
|
||||||
|
new File(dest.getParent().toString()).mkdirs();
|
||||||
|
Files.copy(src, dest, StandardCopyOption.COPY_ATTRIBUTES);
|
||||||
|
} else throw new IOException("A mod requested access to the file \"" + e + "\" from archive " + r + " but it wasn't there!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!m.extracts.isEmpty()) {
|
||||||
|
System.out.println("WARNING: " + m.friendlyName + " by " + m.author + "tried to extract individual files without specifying a source PSARC in requires[]. Ignoring.");
|
||||||
|
consoleDisplay.append("WARNING: " + m.friendlyName + " by " + m.author + "tried to extract individual files without specifying a source PSARC in requires[]. Ignoring." + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
File fscript = new File(Main.inpath + "temp/fscript");
|
File fscript = new File(Main.inpath + "temp/fscript");
|
||||||
if (fscript.exists()) {
|
if (fscript.exists()) {
|
||||||
new Rizzo(fscript, Main.inpath + "temp/"); // Lets rizz this mod up
|
System.out.println("Firestar is applying patches from " + m.friendlyName + " by " + m.author);
|
||||||
|
consoleDisplay.append("Firestar is applying patches from " + m.friendlyName + " by " + m.author + "\n");
|
||||||
|
new Rizzo(new FileInputStream(fscript), Main.inpath + "temp/"); // Lets rizz this mod up
|
||||||
|
fscript.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new File(System.getProperty("user.home") + "/.firestar/temp/delete.txt").isFile()) {
|
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);
|
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");
|
consoleDisplay.append("Firestar is deleting files that conflict with " + m.friendlyName + " by " + m.author + "\n");
|
||||||
|
System.out.println("WARNING: delete.txt is DEPRECATED. If using a mod with loaderversion >= 1 then this is bad practice, please use FSCRIPTs instead.");
|
||||||
|
consoleDisplay.append("WARNING: delete.txt is DEPRECATED. If using a mod with loaderversion >= 1 then this is bad practice, please use FSCRIPTs instead.");
|
||||||
|
|
||||||
String deleteQueue = new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "/.firestar/temp/delete.txt")));
|
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
|
if (Main.windows) {deleteQueue = new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "\\.firestar\\temp\\delete.txt")));} // might be unnecessary
|
||||||
@@ -200,14 +248,15 @@ public class Gonzo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup so we don't run it again for the next mod unless needed
|
// cleanup so we don't run it again for the next mod
|
||||||
// this is not necessary but good practice
|
|
||||||
new File(System.getProperty("user.home") + "/.firestar/temp/delete.txt").delete();
|
new File(System.getProperty("user.home") + "/.firestar/temp/delete.txt").delete();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println(e.getMessage());
|
System.out.println(e.getMessage());
|
||||||
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
|
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
|
||||||
|
if (e instanceof FirescriptFormatException) {JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage() + "\nOne of your mods has a broken FSCRIPT. It cannot be installed.", "Fatal Error", JOptionPane.ERROR_MESSAGE);} else {
|
||||||
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||||
AllowExit();
|
AllowExit();
|
||||||
return;
|
return;
|
||||||
@@ -215,6 +264,18 @@ public class Gonzo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Post fscript changes
|
||||||
|
try (InputStream is = Main.class.getResourceAsStream("/post.fscript")) {
|
||||||
|
new Rizzo(is, Main.inpath + "temp/");
|
||||||
|
} catch (IOException | FirescriptFormatException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
|
||||||
|
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: Internal FSCRIPT Error. " + e.getMessage() + "\nThis may indicate that Firestar has been corrupted and needs reinstalling.", "Fatal Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||||
|
AllowExit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// create a list of the contents of data/ for psp2psarc.exe to read from
|
// 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>();
|
||||||
List<String> oFilesList2 = new ArrayList<String>();
|
List<String> oFilesList2 = new ArrayList<String>();
|
||||||
@@ -253,7 +314,7 @@ public class Gonzo {
|
|||||||
try {
|
try {
|
||||||
System.out.println("Firestar is compiling the final build");
|
System.out.println("Firestar is compiling the final build");
|
||||||
consoleDisplay.append("Firestar is compiling the final build" + "\n");
|
consoleDisplay.append("Firestar is compiling the final build" + "\n");
|
||||||
Process p = Main.exec(new String[]{"../psp2psarc.exe", "create", "--skip-missing-files", "-j12", "-a", "-i", "-y", "--input-file=list.txt", "-o" + oArcTarget}, System.getProperty("user.home") + "/.firestar/temp/");
|
Process p = Main.exec(new String[]{Main.inpath + "psp2psarc.exe", "create", "--skip-missing-files", "-j12", "-a", "-i", "-y", "--input-file=list.txt", "-o" + oArcTarget}, System.getProperty("user.home") + "/.firestar/temp/");
|
||||||
final Thread ioThread = new Thread() {
|
final Thread ioThread = new Thread() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -302,7 +363,9 @@ public class Gonzo {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
File tmp = new File(System.getProperty("user.home") + "/.firestar/temp/");
|
File tmp = new File(System.getProperty("user.home") + "/.firestar/temp/");
|
||||||
|
File tmp2 = new File(System.getProperty("user.home") + "/.firestar/temparcs/");
|
||||||
Main.deleteDir(tmp);
|
Main.deleteDir(tmp);
|
||||||
|
Main.deleteDir(tmp2);
|
||||||
} catch (Exception e) {
|
} catch (Exception 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());
|
||||||
@@ -335,17 +398,15 @@ public class Gonzo {
|
|||||||
@Override
|
@Override
|
||||||
public void windowClosing(WindowEvent e)
|
public void windowClosing(WindowEvent e)
|
||||||
{
|
{
|
||||||
|
Main.deleteDir(new File(System.getProperty("user.home") + "/.firestar/temp/"));
|
||||||
invoker.wrapUpDeployment();
|
invoker.wrapUpDeployment();
|
||||||
e.getWindow().dispose();
|
e.getWindow().dispose();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void listAllFiles(Path currentPath, List<String> allFiles)
|
private static void listAllFiles(Path currentPath, List<String> allFiles) throws IOException {
|
||||||
throws IOException
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(currentPath)) {
|
||||||
{
|
|
||||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(currentPath))
|
|
||||||
{
|
|
||||||
for (Path entry : stream) {
|
for (Path entry : stream) {
|
||||||
if (Files.isDirectory(entry)) {
|
if (Files.isDirectory(entry)) {
|
||||||
listAllFiles(entry, allFiles);
|
listAllFiles(entry, allFiles);
|
||||||
|
|||||||
@@ -18,12 +18,17 @@
|
|||||||
|
|
||||||
import net.lingala.zip4j.ZipFile;
|
import net.lingala.zip4j.ZipFile;
|
||||||
import net.lingala.zip4j.exception.ZipException;
|
import net.lingala.zip4j.exception.ZipException;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.json.*;
|
import org.json.*;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
@@ -31,11 +36,16 @@ import javax.swing.*;
|
|||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
// Build Information
|
// Build Information
|
||||||
public static final String vstr = "Release 1.3";
|
public static String vstr = "Release 1.3.1";
|
||||||
public static final String vcode = "Tetsuo";
|
public static final String vcode = "Tetsuo";
|
||||||
public static final String vtag = "tetsuo-1.3"; // set to dekka-1.1 for testing
|
public static final String vtag = "tetsuo-1.3.1"; // set to dekka-1.1 for testing
|
||||||
public static final int vint = 1;
|
public static final int vint = 1;
|
||||||
|
|
||||||
|
// Jenkins Build Information
|
||||||
|
public static boolean isNightly = false;
|
||||||
|
public static final String vtagPrevious = "tetsuo-1.3.1";
|
||||||
|
public static String dateOfCompile = null;
|
||||||
|
|
||||||
// User Settings
|
// User Settings
|
||||||
public static String outpath = System.getProperty("user.home") + "/.firestar/out/"; //game assets location
|
public static String outpath = System.getProperty("user.home") + "/.firestar/out/"; //game assets location
|
||||||
public final static String inpath = System.getProperty("user.home") + "/.firestar/"; //firestar folder -- do not change this
|
public final static String inpath = System.getProperty("user.home") + "/.firestar/"; //firestar folder -- do not change this
|
||||||
@@ -47,6 +57,7 @@ public class Main {
|
|||||||
|
|
||||||
public enum ArcTarget { // install target for 2048, type used by downloader
|
public enum ArcTarget { // install target for 2048, type used by downloader
|
||||||
BASE("http://zeus.dl.playstation.net/cdn/UP9000/PCSA00015_00/NYEoaBGfiWymSEVZKxoyrKyBFsZNoFqxdyAIpZayZYuLLbCAArYrYXjPNhKCfXcONmhIZzZEeArycSrjiJOuNMWuWsDONUxMIQtMk.pkg"),
|
BASE("http://zeus.dl.playstation.net/cdn/UP9000/PCSA00015_00/NYEoaBGfiWymSEVZKxoyrKyBFsZNoFqxdyAIpZayZYuLLbCAArYrYXjPNhKCfXcONmhIZzZEeArycSrjiJOuNMWuWsDONUxMIQtMk.pkg"),
|
||||||
|
FIRST("http://gs.ww.np.dl.playstation.net/ppkg/np/PCSA00015/PCSA00015_T5/a4b7d9e35ed56e86/UP9000-PCSA00015_00-WIPEOUT2048BASE0-A0104-V0100-059564fcab8ce66d19b5a563e92677e581313205-PE.pkg"),
|
||||||
LATEST("http://gs.ww.np.dl.playstation.net/ppkg/np/PCSA00015/PCSA00015_T5/a4b7d9e35ed56e86/UP9000-PCSA00015_00-WIPEOUT2048BASE0-A0104-V0100-059564fcab8ce66d19b5a563e92677e581313205-PE.pkg"),
|
LATEST("http://gs.ww.np.dl.playstation.net/ppkg/np/PCSA00015/PCSA00015_T5/a4b7d9e35ed56e86/UP9000-PCSA00015_00-WIPEOUT2048BASE0-A0104-V0100-059564fcab8ce66d19b5a563e92677e581313205-PE.pkg"),
|
||||||
ADDON_HD("http://zeus.dl.playstation.net/cdn/UP9000/PCSA00015_00/JYMqGNXUKqHEyNLjbOgrWcJdnQJUMzgadRFWekbWFBXAwMeGikOyiHkXKogKIfqGhtNwKgmNWwwcrJORmRUTDzylBPwjGVnVjyDfh.pkg"),
|
ADDON_HD("http://zeus.dl.playstation.net/cdn/UP9000/PCSA00015_00/JYMqGNXUKqHEyNLjbOgrWcJdnQJUMzgadRFWekbWFBXAwMeGikOyiHkXKogKIfqGhtNwKgmNWwwcrJORmRUTDzylBPwjGVnVjyDfh.pkg"),
|
||||||
ADDON_HD_FURY("http://zeus.dl.playstation.net/cdn/UP9000/PCSA00015_00/IAoJQaDpySenBmQCKiqecEPMzSdPfPcdXupxZXLTYYTuRgtsdTaHxbeejwGKRQpjJOKBdMMFzSoeEhsHYxNUasQrEzkZPeBxUEqnp.pkg");
|
ADDON_HD_FURY("http://zeus.dl.playstation.net/cdn/UP9000/PCSA00015_00/IAoJQaDpySenBmQCKiqecEPMzSdPfPcdXupxZXLTYYTuRgtsdTaHxbeejwGKRQpjJOKBdMMFzSoeEhsHYxNUasQrEzkZPeBxUEqnp.pkg");
|
||||||
@@ -62,6 +73,7 @@ public class Main {
|
|||||||
|
|
||||||
public enum ArcKey { // decryption keys for 2048, type used by downloader
|
public enum ArcKey { // decryption keys for 2048, type used by downloader
|
||||||
BASE("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
|
BASE("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
|
||||||
|
FIRST("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
|
||||||
LATEST("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
|
LATEST("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
|
||||||
ADDON_HD("KO5ifR1dQ+eHBlgi6TI0Bdnv4uNsGG5kYGIR4Ojs7ejuis9/anXfuudVNvzgdu+9z1z+asJojA9uAACgRhTl"),
|
ADDON_HD("KO5ifR1dQ+eHBlgi6TI0Bdnv4uNsGG5kYGIR4Ojs7ejuis9/anXfuudVNvzgdu+9z1z+asJojA9uAACgRhTl"),
|
||||||
ADDON_HD_FURY("KO5ifR1dQ+eHBlgi6TI0Bdnv4uNsFG5kYGIR4Ojs7ejuis9/3fydBRm3eCJX7biz/vVTm/2jMT64AQCCYhVy");
|
ADDON_HD_FURY("KO5ifR1dQ+eHBlgi6TI0Bdnv4uNsFG5kYGIR4Ojs7ejuis9/3fydBRm3eCJX7biz/vVTm/2jMT64AQCCYhVy");
|
||||||
@@ -85,8 +97,8 @@ public class Main {
|
|||||||
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;
|
public boolean enabled = true;
|
||||||
public List<boolean[]> requires = new ArrayList<>(); // TODO: load optional "requires" array from mod meta if it exists. it will be base, patches, hd dlc, and fury dlc in that order.
|
public List<String> requires = new ArrayList<>();
|
||||||
// TODO: save 'false true false false' in ost gen if necessary (patches change localization)
|
public List<String> extracts = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mods
|
// Mods
|
||||||
@@ -96,12 +108,26 @@ public class Main {
|
|||||||
public static Font fExo2;
|
public static Font fExo2;
|
||||||
public static BufferedImage windowIcon;
|
public static BufferedImage windowIcon;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
// get Nightly information from Jenkins automatic builds
|
||||||
|
if (Main.class.getResource("/jenkinsVersionString") != null) {
|
||||||
|
System.out.println("=== This is a NIGHTLY BUILD! ===\n");
|
||||||
|
try {
|
||||||
|
vstr = "Nightly " + IOUtils.toString(Main.class.getResourceAsStream("/jenkinsVersionString"), StandardCharsets.UTF_8);
|
||||||
|
dateOfCompile = IOUtils.toString(Main.class.getResourceAsStream("/jenkinsBuildDate"), StandardCharsets.UTF_8);
|
||||||
|
System.out.println("Compiled on " + dateOfCompile);
|
||||||
|
isNightly = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("ERROR: Something went wrong trying to get the autobuild information! defaulting to Release values\n\n");
|
||||||
|
isNightly = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// license string
|
// license string
|
||||||
System.out.printf("FIRESTAR MOD MANAGER for WipEout 2048\nversion " + vstr + " (codename " + vcode + ") major " + vint + "\n" +
|
System.out.printf("FIRESTAR MOD MANAGER for WipEout 2048\n" + vstr + " (codename " + vcode + ") major " + vint + "\n" +
|
||||||
"JVM host appears to be " + System.getProperty("os.name") +
|
"JVM host appears to be " + System.getProperty("os.name") +
|
||||||
"\nRunning from " + System.getProperty("user.dir") +
|
"\nRunning from " + System.getProperty("user.dir") +
|
||||||
"\nCopyright (C) 2024 bonkmaykr\n\nThis program is free software: you can redistribute it and/or modify\n" +
|
"\nCopyright (C) 2025 Canithesis Interactive\n\nThis program is free software: you can redistribute it and/or modify\n" +
|
||||||
"it under the terms of the GNU General Public License as published by\n" +
|
"it under the terms of the GNU General Public License as published by\n" +
|
||||||
"the Free Software Foundation, either version 3 of the License, or\n" +
|
"the Free Software Foundation, either version 3 of the License, or\n" +
|
||||||
"(at your option) any later version.\n" +
|
"(at your option) any later version.\n" +
|
||||||
@@ -114,7 +140,9 @@ public class Main {
|
|||||||
"You should have received a copy of the GNU General Public License\n" +
|
"You should have received a copy of the GNU General Public License\n" +
|
||||||
"along with this program. If not, see https://www.gnu.org/licenses/.\n\n\n\n");
|
"along with this program. If not, see https://www.gnu.org/licenses/.\n\n\n\n");
|
||||||
|
|
||||||
//begin
|
// display splash screen
|
||||||
|
new Beaker();
|
||||||
|
|
||||||
// load global assets
|
// load global assets
|
||||||
try {
|
try {
|
||||||
fExo2 = Font.createFont(Font.TRUETYPE_FONT, Main.class.getResourceAsStream("/exo2.ttf"));
|
fExo2 = Font.createFont(Font.TRUETYPE_FONT, Main.class.getResourceAsStream("/exo2.ttf"));
|
||||||
@@ -216,10 +244,25 @@ public class Main {
|
|||||||
Main.writeConf();
|
Main.writeConf();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean downloadDependencies () { // todo: CHECKSUM!!!! THESE ARE EXECUTABLES!!!!!!!!!!! DON'T ALLOW MALWARE!!!!
|
public static boolean downloadDependencies () {
|
||||||
boolean downloader = new Fozzie().DownloadFile("https://bonkmaykr.worlio.com/http/firestar/firesdk.zip", System.getProperty("user.home") + "/.firestar/", "firesdk.zip");
|
boolean downloader = new Fozzie().DownloadFile("https://bonkmaykr.worlio.com/http/firestar/fire13.zip", System.getProperty("user.home") + "/.firestar/", "firesdk.zip", "Firestar dependencies");
|
||||||
if (!downloader) {return false;}
|
if (!downloader) {return false;}
|
||||||
|
|
||||||
|
final String expectedMD5Hash = "306807955266724172476879569959042600238"; // Prevent a malicious web server takeover from installing malware on the user's computer.
|
||||||
|
String downloadedMD5Hash = ""; // if this number does not match for ANY reason, cancel immediately and get a programmer.
|
||||||
|
try {downloadedMD5Hash = new BigInteger(1, MessageDigest.getInstance("MD5").digest(Files.readAllBytes(Paths.get(Main.inpath + "firesdk.zip")))).toString();}
|
||||||
|
catch (Exception e) {
|
||||||
|
System.out.println("ERROR: Failed to download PSARC tool due to an internal problem.\n" + e.getMessage());
|
||||||
|
JOptionPane.showMessageDialog(null, "The file failed to download.\nPlease check your network connection and try again.\n\n" + e.getMessage(), "Download Failed", JOptionPane.WARNING_MESSAGE);
|
||||||
|
}
|
||||||
|
if (!downloadedMD5Hash.equals(expectedMD5Hash)) {
|
||||||
|
System.out.println("ERROR: Downloaded PSARC tool is invalid. Check your network connection and ensure the file is not corrupt or infected.");
|
||||||
|
//Object[] options = {"Abort", "Retry"};
|
||||||
|
//int result = JOptionPane.showOptionDialog(new JFrame(), "The downloaded file failed a security check.\nPlease ensure your network connection is stable.\n\nIf this issue persists, send an email to tech support\nat bonkmaykr@screwgravity.net.", "Download Cancelled", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]);
|
||||||
|
JOptionPane.showMessageDialog(null, "The downloaded file failed a security check.\nPlease ensure your network connection is stable.\n\nIf this issue persists, send an email to tech support\nat bonkmaykr@screwgravity.net.", "Download Cancelled", JOptionPane.WARNING_MESSAGE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ZipFile sdk = new ZipFile(System.getProperty("user.home") + "/.firestar/firesdk.zip");
|
ZipFile sdk = new ZipFile(System.getProperty("user.home") + "/.firestar/firesdk.zip");
|
||||||
try {
|
try {
|
||||||
sdk.extractAll(System.getProperty("user.home") + "/.firestar/");
|
sdk.extractAll(System.getProperty("user.home") + "/.firestar/");
|
||||||
@@ -230,13 +273,10 @@ public class Main {
|
|||||||
}
|
}
|
||||||
sdk.getFile().delete(); // cleanup
|
sdk.getFile().delete(); // cleanup
|
||||||
|
|
||||||
|
JOptionPane.showMessageDialog(null, "All remote dependencies satisfied.", "Download Completed", JOptionPane.INFORMATION_MESSAGE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean callDownloaderStatically (String url, String folder, String name) {
|
|
||||||
return new Fozzie().DownloadFile(url, folder, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Process exec(String[] cmd, String cwd) throws IOException {
|
public static Process exec(String[] cmd, String cwd) throws IOException {
|
||||||
Process p;
|
Process p;
|
||||||
String[] pcmd;
|
String[] pcmd;
|
||||||
@@ -250,4 +290,16 @@ public class Main {
|
|||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void printProcessLogToStdOut(Process p) {
|
||||||
|
try {
|
||||||
|
final BufferedReader reader = new BufferedReader(
|
||||||
|
new InputStreamReader(p.getInputStream()));
|
||||||
|
String line = null;
|
||||||
|
while ((line = reader.readLine()) != null) {System.out.println(line);}
|
||||||
|
reader.close();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -31,8 +31,11 @@ import java.math.RoundingMode;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
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.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import net.lingala.zip4j.*;
|
import net.lingala.zip4j.*;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@@ -172,7 +175,7 @@ public class MissPiggy implements ActionListener {
|
|||||||
frame.setLayout(new GridLayout());
|
frame.setLayout(new GridLayout());
|
||||||
frame.setLocationRelativeTo(null);
|
frame.setLocationRelativeTo(null);
|
||||||
|
|
||||||
if (Main.checkUpdates) { StartErnie(); }
|
if (Main.checkUpdates) { StartErnie(false); }
|
||||||
|
|
||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
}
|
}
|
||||||
@@ -199,8 +202,9 @@ public class MissPiggy implements ActionListener {
|
|||||||
|
|
||||||
// initialize data structures from each list entry
|
// initialize data structures from each list entry
|
||||||
String[] pListArray = priorityList.split("\n");
|
String[] pListArray = priorityList.split("\n");
|
||||||
Arrays.sort(pListArray);
|
Arrays.sort(pListArray, new NaturalOrderComparator<>(false));
|
||||||
System.out.println("Initializing modList from file with length of " + pListArray.length + " units"); //debug
|
System.out.println("Initializing modList from file with length of " + pListArray.length + " units"); //debug
|
||||||
|
|
||||||
for (String s : pListArray) {
|
for (String s : pListArray) {
|
||||||
/*
|
/*
|
||||||
Do nothing if the index number is not valid.
|
Do nothing if the index number is not valid.
|
||||||
@@ -209,7 +213,6 @@ 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());
|
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]+=*") &&
|
||||||
@@ -230,6 +233,16 @@ public class MissPiggy implements ActionListener {
|
|||||||
if (metadata.has("loaderversion")) {m.loaderversion = Integer.parseInt(metadata.get("loaderversion").toString());}
|
if (metadata.has("loaderversion")) {m.loaderversion = Integer.parseInt(metadata.get("loaderversion").toString());}
|
||||||
if (metadata.has("game")) {m.game = metadata.get("game").toString();}
|
if (metadata.has("game")) {m.game = metadata.get("game").toString();}
|
||||||
|
|
||||||
|
if (m.loaderversion >= 1) {
|
||||||
|
// Firestar 1.3 features
|
||||||
|
if (metadata.has("requires"))
|
||||||
|
for (Object i : (ArrayList<Object>)((Map<String, Object>)metadata.toMap()).get("requires"))
|
||||||
|
m.requires.add(i.toString());
|
||||||
|
if (metadata.has("extracts"))
|
||||||
|
for (Object i : (ArrayList<Object>)((Map<String, Object>)metadata.toMap()).get("extracts"))
|
||||||
|
m.extracts.add(i.toString());
|
||||||
|
}
|
||||||
|
|
||||||
//send to list
|
//send to list
|
||||||
Main.Mods.add(m);
|
Main.Mods.add(m);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -284,13 +297,14 @@ public class MissPiggy implements ActionListener {
|
|||||||
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()) {
|
||||||
if (Main.Mods.get(i).friendlyName == null || Main.Mods.get(i).friendlyName.isEmpty())
|
if (Main.Mods.get(i).friendlyName == null || Main.Mods.get(i).friendlyName.isEmpty())
|
||||||
{Main.Mods.get(i).friendlyName = Main.Mods.get(i).path;}
|
Main.Mods.get(i).friendlyName = Main.Mods.get(i).path;
|
||||||
if (Main.Mods.get(i).enabled) {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)";}
|
else {contents[i] = Main.Mods.get(i).friendlyName + " (Disabled)";}
|
||||||
|
|
||||||
//debug
|
//debug
|
||||||
String authorDisplay;
|
String authorDisplay;
|
||||||
if (Main.Mods.get(i).author == null || Main.Mods.get(i).author.isEmpty()) {authorDisplay = "Anonymous";} else {authorDisplay = "\"" + Main.Mods.get(i).author + "\"";}
|
if (Main.Mods.get(i).author == null || Main.Mods.get(i).author.isEmpty()) {authorDisplay = "Anonymous";}
|
||||||
|
else {authorDisplay = "\"" + Main.Mods.get(i).author + "\"";}
|
||||||
System.out.println("Added " + Main.Mods.get(i).friendlyName + " by " + authorDisplay);
|
System.out.println("Added " + Main.Mods.get(i).friendlyName + " by " + authorDisplay);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
@@ -299,11 +313,11 @@ public class MissPiggy implements ActionListener {
|
|||||||
createSelectionEventListener();
|
createSelectionEventListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartErnie() {
|
private void StartErnie(boolean isManual) {
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
new Ernie(frame); // changed away from runnable in order to pass params to constructor -bonk
|
new Ernie(frame, isManual); // changed away from runnable in order to pass params to constructor -bonk
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
@@ -331,7 +345,11 @@ public class MissPiggy implements ActionListener {
|
|||||||
|
|
||||||
if (actionEvent.getSource() == toolsMenu.getItem(0)) {metaEditorGUI(modList.getSelectedIndex());} else
|
if (actionEvent.getSource() == toolsMenu.getItem(0)) {metaEditorGUI(modList.getSelectedIndex());} else
|
||||||
if (actionEvent.getSource() == toolsMenu.getItem(1)) {generatorGUI();} else
|
if (actionEvent.getSource() == toolsMenu.getItem(1)) {generatorGUI();} else
|
||||||
if (actionEvent.getSource() == toolsMenu.getItem(2)) {new Suggs(frame);} else
|
if (actionEvent.getSource() == toolsMenu.getItem(2)) {
|
||||||
|
if (!new File(Main.inpath + "at9tool.exe").exists() || !new File(Main.inpath + "ffmpeg.exe").exists())
|
||||||
|
JOptionPane.showMessageDialog(frame, "Your AT9 encoders are missing.\nPlease select \"Get Dependencies\" in the Options menu.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
else new Suggs(frame);
|
||||||
|
} else
|
||||||
|
|
||||||
if (actionEvent.getSource() == helpMenu.getItem(0)) {
|
if (actionEvent.getSource() == helpMenu.getItem(0)) {
|
||||||
try {
|
try {
|
||||||
@@ -357,7 +375,7 @@ public class MissPiggy implements ActionListener {
|
|||||||
JOptionPane.showMessageDialog(frame, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(frame, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
if (actionEvent.getSource() == helpMenu.getItem(5)) {StartErnie();} else
|
if (actionEvent.getSource() == helpMenu.getItem(5)) {StartErnie(true);} else
|
||||||
if (actionEvent.getSource() == helpMenu.getItem(6)) {new Rowlf(frame);}
|
if (actionEvent.getSource() == helpMenu.getItem(6)) {new Rowlf(frame);}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,7 +477,6 @@ public class MissPiggy implements ActionListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void removeAllGUI() {
|
public void removeAllGUI() {
|
||||||
// todo warning dialog that nukes list when Yes is clicked
|
|
||||||
int result = JOptionPane.showConfirmDialog(frame, "Do you really want to delete all mods?", "Remove All", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
|
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) {
|
if (result == JOptionPane.YES_OPTION) {
|
||||||
@@ -515,20 +532,20 @@ public class MissPiggy implements ActionListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void moveUp(int index) {
|
private void moveUp(int index) {
|
||||||
if (index > 0) {
|
if (index > 0) { // not negative
|
||||||
Collections.swap(Main.Mods, index, index - 1);
|
Collections.swap(Main.Mods, index, index - 1);
|
||||||
System.out.println("Items moved, redeploying list");
|
System.out.println("Items moved, redeploying list");
|
||||||
InitializeModListInGUI();
|
regenerateModIndex(true);
|
||||||
regenerateModIndex(false);
|
modList.setSelectedIndex(index - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void moveDown(int index) {
|
private void moveDown(int index) {
|
||||||
if (index < (Main.Mods.size() - 1)) {
|
if (index < (Main.Mods.size() - 1)) { // not last in list
|
||||||
Collections.swap(Main.Mods, index, index + 1);
|
Collections.swap(Main.Mods, index, index + 1);
|
||||||
System.out.println("Items moved, redeploying list");
|
System.out.println("Items moved, redeploying list");
|
||||||
InitializeModListInGUI();
|
regenerateModIndex(true);
|
||||||
regenerateModIndex(false);
|
modList.setSelectedIndex(index + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,6 +553,7 @@ public class MissPiggy implements ActionListener {
|
|||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
Main.Mods.get(index).enabled = !Main.Mods.get(index).enabled;
|
Main.Mods.get(index).enabled = !Main.Mods.get(index).enabled;
|
||||||
regenerateModBlacklist(true);
|
regenerateModBlacklist(true);
|
||||||
|
modList.setSelectedIndex(index);
|
||||||
} else {
|
} else {
|
||||||
JOptionPane.showMessageDialog(frame, "Please select a mod to toggle first.", "Error", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(frame, "Please select a mod to toggle first.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
@@ -593,7 +611,6 @@ public class MissPiggy implements ActionListener {
|
|||||||
int result = JOptionPane.showConfirmDialog(frame, "Firestar encountered an internal error.\n" + ex.getMessage(), "Fatal Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE);
|
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
|
if (result == JOptionPane.OK_OPTION) {System.exit(1);} //user safety
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
185
firestar/src/main/java/NaturalOrderComparator.java
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
* <copyright>
|
||||||
|
*
|
||||||
|
* Copyright 1997-2007 BBNT Solutions, LLC
|
||||||
|
* under sponsorship of the Defense Advanced Research Projects
|
||||||
|
* Agency (DARPA).
|
||||||
|
*
|
||||||
|
* You can redistribute this software and/or modify it under the
|
||||||
|
* terms of the Cougaar Open Source License as published on the
|
||||||
|
* Cougaar Open Source Website (www.cougaar.org).
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* </copyright>
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
NaturalOrderComparator.java -- Perform 'natural order' comparisons of strings in Java.
|
||||||
|
Copyright (C) 2003 by Pierre-Luc Paour <natorder@paour.com>
|
||||||
|
|
||||||
|
Based on the C version by Martin Pool, of which this is more or less a straight conversion.
|
||||||
|
Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//CHANGES: KD - added case sensitive ordering capability
|
||||||
|
// Made comparison so it doesn't treat spaces as special characters
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A sorting comparator to sort strings numerically,
|
||||||
|
* ie [1, 2, 10], as opposed to [1, 10, 2].
|
||||||
|
*/
|
||||||
|
public final class NaturalOrderComparator<T> implements Comparator<T> {
|
||||||
|
|
||||||
|
public static final Comparator<String> NUMERICAL_ORDER = new NaturalOrderComparator<String>(false);
|
||||||
|
public static final Comparator<String> CASEINSENSITIVE_NUMERICAL_ORDER = new NaturalOrderComparator<String>(true);
|
||||||
|
|
||||||
|
private final boolean caseInsensitive;
|
||||||
|
|
||||||
|
public NaturalOrderComparator(boolean caseInsensitive) {
|
||||||
|
this.caseInsensitive = caseInsensitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
int compareRight(String a, String b) {
|
||||||
|
int bias = 0;
|
||||||
|
int ia = 0;
|
||||||
|
int ib = 0;
|
||||||
|
|
||||||
|
// The longest run of digits wins. That aside, the greatest
|
||||||
|
// value wins, but we can't know that it will until we've scanned
|
||||||
|
// both numbers to know that they have the same magnitude, so we
|
||||||
|
// remember it in BIAS.
|
||||||
|
for (;; ia++, ib++) {
|
||||||
|
char ca = charAt(a, ia);
|
||||||
|
char cb = charAt(b, ib);
|
||||||
|
|
||||||
|
if (!Character.isDigit(ca) && !Character.isDigit(cb)) {
|
||||||
|
return bias;
|
||||||
|
} else if (!Character.isDigit(ca)) {
|
||||||
|
return -1;
|
||||||
|
} else if (!Character.isDigit(cb)) {
|
||||||
|
return +1;
|
||||||
|
} else if (ca < cb) {
|
||||||
|
if (bias == 0) {
|
||||||
|
bias = -1;
|
||||||
|
}
|
||||||
|
} else if (ca > cb) {
|
||||||
|
if (bias == 0)
|
||||||
|
bias = +1;
|
||||||
|
} else if (ca == 0 && cb == 0) {
|
||||||
|
return bias;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compare(T o1, T o2) {
|
||||||
|
String a = o1.toString();
|
||||||
|
String b = o2.toString();
|
||||||
|
|
||||||
|
int ia = 0, ib = 0;
|
||||||
|
int nza = 0, nzb = 0;
|
||||||
|
char ca, cb;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
// only count the number of zeroes leading the last number compared
|
||||||
|
nza = nzb = 0;
|
||||||
|
|
||||||
|
ca = charAt(a, ia);
|
||||||
|
cb = charAt(b, ib);
|
||||||
|
|
||||||
|
// skip over leading zeros
|
||||||
|
while (ca == '0') {
|
||||||
|
if (ca == '0') {
|
||||||
|
nza++;
|
||||||
|
} else {
|
||||||
|
// only count consecutive zeroes
|
||||||
|
nza = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the next character isn't a digit, then we've had a run of only zeros
|
||||||
|
// we still need to treat this as a 0 for comparison purposes
|
||||||
|
if (!Character.isDigit(charAt(a, ia+1)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
ca = charAt(a, ++ia);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (cb == '0') {
|
||||||
|
if (cb == '0') {
|
||||||
|
nzb++;
|
||||||
|
} else {
|
||||||
|
// only count consecutive zeroes
|
||||||
|
nzb = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the next character isn't a digit, then we've had a run of only zeros
|
||||||
|
// we still need to treat this as a 0 for comparison purposes
|
||||||
|
if (!Character.isDigit(charAt(b, ib+1)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
cb = charAt(b, ++ib);
|
||||||
|
}
|
||||||
|
|
||||||
|
// process run of digits
|
||||||
|
if (Character.isDigit(ca) && Character.isDigit(cb)) {
|
||||||
|
if ((result = compareRight(a.substring(ia), b
|
||||||
|
.substring(ib))) != 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ca == 0 && cb == 0) {
|
||||||
|
// The strings compare the same. Perhaps the caller
|
||||||
|
// will want to call strcmp to break the tie.
|
||||||
|
return nza - nzb;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ca < cb) {
|
||||||
|
return -1;
|
||||||
|
} else if (ca > cb) {
|
||||||
|
return +1;
|
||||||
|
}
|
||||||
|
|
||||||
|
++ia;
|
||||||
|
++ib;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private char charAt(String s, int i) {
|
||||||
|
if (i >= s.length()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return caseInsensitive ? Character.toUpperCase(s.charAt(i)) : s.charAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ import java.util.Iterator;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Created by simon on 8/29/17.
|
* Created by simon on 8/29/17.
|
||||||
* Copyright 2017 Simon Haoran Liang
|
* Copyright 2017 Simon Haoran Liang
|
||||||
*
|
*
|
||||||
@@ -130,8 +130,7 @@ public class ReplacingInputStream extends FilterInputStream {
|
|||||||
}
|
}
|
||||||
b[off + i] = (byte)c;
|
b[off + i] = (byte)c;
|
||||||
}
|
}
|
||||||
} catch (IOException ee) {
|
} catch (IOException ee) { }
|
||||||
}
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,6 +28,7 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@@ -45,21 +46,20 @@ import javax.xml.transform.TransformerException;
|
|||||||
import javax.xml.transform.TransformerFactory;
|
import javax.xml.transform.TransformerFactory;
|
||||||
import javax.xml.transform.dom.DOMSource;
|
import javax.xml.transform.dom.DOMSource;
|
||||||
import javax.xml.transform.stream.StreamResult;
|
import javax.xml.transform.stream.StreamResult;
|
||||||
import org.w3c.dom.Attr;
|
import javax.xml.transform.OutputKeys;
|
||||||
import org.w3c.dom.Document;
|
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.*;
|
||||||
import org.w3c.dom.NamedNodeMap;
|
|
||||||
import org.w3c.dom.Node;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
import org.apache.commons.text.StringEscapeUtils;
|
||||||
|
|
||||||
public class Rizzo {
|
public class Rizzo {
|
||||||
|
private final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||||
private Scanner scanner;
|
private Scanner scanner;
|
||||||
private final int maxVer = 1;
|
private final int maxVer = 1;
|
||||||
private int ver = 1;
|
private int ver = 1;
|
||||||
private String workingDir;
|
private String workingDir;
|
||||||
|
|
||||||
public Rizzo(File infile, String workingDir) throws FileNotFoundException, FirescriptFormatException {
|
public Rizzo(InputStream infile, String workingDir) throws FileNotFoundException, FirescriptFormatException {
|
||||||
if (!workingDir.endsWith("/")) this.workingDir = workingDir + "/";
|
if (!workingDir.endsWith("/")) this.workingDir = workingDir + "/";
|
||||||
else this.workingDir = workingDir;
|
else this.workingDir = workingDir;
|
||||||
scanner = new Scanner(infile);
|
scanner = new Scanner(infile);
|
||||||
@@ -85,17 +85,17 @@ public class Rizzo {
|
|||||||
File newCtx = new File(workingDir + args[1]);
|
File newCtx = new File(workingDir + args[1]);
|
||||||
System.out.println("Calling new parse: " + Arrays.toString(Arrays.copyOfRange(args, 2, args.length)));
|
System.out.println("Calling new parse: " + Arrays.toString(Arrays.copyOfRange(args, 2, args.length)));
|
||||||
parseArgs(Arrays.copyOfRange(args, 2, args.length), newCtx);
|
parseArgs(Arrays.copyOfRange(args, 2, args.length), newCtx);
|
||||||
} else throw new FirescriptFormatException("fscript", "unknown command '" + args[0] + "'");
|
} else throw new FirescriptFormatException("fscript", "command '" + args[0] + "' is unknown or used in inappropriate context");
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Parsing Command: " + Arrays.toString(args) + " with context: " + context.getClass().getName() + "@" + context.hashCode());
|
System.out.println("Parsing Command: " + Arrays.toString(args) + " using context: " + context.getClass().getName() + "@" + context.hashCode());
|
||||||
if (args[0].equals("{")) {
|
if (args[0].equals("{")) {
|
||||||
System.out.println("New context parse: " + context.getClass().getName() + "@" + context.hashCode());
|
System.out.println("New context block: " + context.getClass().getName() + "@" + context.hashCode());
|
||||||
parseScript(context);
|
parseScript(context);
|
||||||
} else if (args[0].equals("}")) {
|
} else if (args[0].equals("}")) {
|
||||||
System.out.println("Ending context block: " + context.getClass().getName() + "@" + context.hashCode());
|
System.out.println("Ending context block: " + context.getClass().getName() + "@" + context.hashCode());
|
||||||
return false;
|
return false;
|
||||||
} else if (context instanceof File file) {
|
} else if (context instanceof File file) {
|
||||||
if (!file.exists()) return true;
|
if (file.exists()) {
|
||||||
if (args[0].equalsIgnoreCase("delete")) {
|
if (args[0].equalsIgnoreCase("delete")) {
|
||||||
System.out.println("Deleting: " + file.getPath());
|
System.out.println("Deleting: " + file.getPath());
|
||||||
if (file.getAbsolutePath().startsWith(workingDir)) {
|
if (file.getAbsolutePath().startsWith(workingDir)) {
|
||||||
@@ -104,10 +104,9 @@ public class Rizzo {
|
|||||||
}
|
}
|
||||||
} else if (args[0].equalsIgnoreCase("xml")) {
|
} else if (args[0].equalsIgnoreCase("xml")) {
|
||||||
try {
|
try {
|
||||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
|
||||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||||
// Mmmm, love me some INVALID XML corrections
|
// Mmmm, love me some INVALID XML corrections.
|
||||||
ReplacingInputStream ris = new ReplacingInputStream(new FileInputStream(file), "&", "&");
|
ReplacingInputStream ris = new ReplacingInputStream(new ReplacingInputStream(new ReplacingInputStream(new FileInputStream(file), "\r\n", ""), "&", "&"), "\n", " ");
|
||||||
Document doc = docBuilder.parse(ris);
|
Document doc = docBuilder.parse(ris);
|
||||||
parseArgs(Arrays.copyOfRange(args, 1, args.length), doc);
|
parseArgs(Arrays.copyOfRange(args, 1, args.length), doc);
|
||||||
try {
|
try {
|
||||||
@@ -117,15 +116,11 @@ public class Rizzo {
|
|||||||
StreamResult result = new StreamResult(new StringWriter());
|
StreamResult result = new StreamResult(new StringWriter());
|
||||||
DOMSource source = new DOMSource(doc);
|
DOMSource source = new DOMSource(doc);
|
||||||
|
|
||||||
|
// WipEout 2048 will pretend to be happy with these self-closed tags but in actuality, it is screaming on the inside.
|
||||||
|
transformer.setOutputProperty(OutputKeys.METHOD, "html");
|
||||||
transformer.transform(source, result);
|
transformer.transform(source, result);
|
||||||
// Look ma, I'm breaking XML standards!
|
// Look ma, I'm breaking XML standards!
|
||||||
String xmlString = result.getWriter().toString()
|
String xmlString = StringEscapeUtils.unescapeHtml4(result.getWriter().toString());
|
||||||
.replace("&", "&")
|
|
||||||
.replace("	", "\t")
|
|
||||||
.replace("", "\b")
|
|
||||||
.replace(" ", "\n")
|
|
||||||
.replace(" ", "\r")
|
|
||||||
.replace("", "\f");
|
|
||||||
try (PrintStream ps = new PrintStream(output)) {
|
try (PrintStream ps = new PrintStream(output)) {
|
||||||
ps.print(xmlString);
|
ps.print(xmlString);
|
||||||
}
|
}
|
||||||
@@ -133,7 +128,7 @@ public class Rizzo {
|
|||||||
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
} catch (SAXException | IOException | ParserConfigurationException ex) {
|
} catch (SAXException | IOException | ParserConfigurationException ex) {
|
||||||
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, "This usually means there's non-standard formatting from the game developer which your FSCRIPT does not account for.", ex);
|
||||||
}
|
}
|
||||||
} else if (args[0].equalsIgnoreCase("str") || args[0].equalsIgnoreCase("xstr")) {
|
} else if (args[0].equalsIgnoreCase("str") || args[0].equalsIgnoreCase("xstr")) {
|
||||||
try {
|
try {
|
||||||
@@ -200,10 +195,21 @@ public class Rizzo {
|
|||||||
} catch (FirescriptFormatException | PatchFailedException | IOException ex) {
|
} catch (FirescriptFormatException | PatchFailedException | IOException ex) {
|
||||||
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
} else throw new FirescriptFormatException("file", "unknown command '" + args[0] + "'");
|
} else throw new FirescriptFormatException("file", "command '" + args[0] + "' is unknown or used in inappropriate context");
|
||||||
|
} else if (args[0].equalsIgnoreCase("xml")) {
|
||||||
|
System.out.println("fscript: XML called but file does not exist. Using placebo...");
|
||||||
|
try {
|
||||||
|
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||||
|
parseArgs(Arrays.copyOfRange(args, 1, args.length), docBuilder.newDocument());
|
||||||
|
} catch (ParserConfigurationException ex1) {
|
||||||
|
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex1);
|
||||||
|
throw new FirescriptFormatException("xml", "critical document failure");
|
||||||
|
}
|
||||||
|
} else System.out.println("fscript: file context not found, skipping.");
|
||||||
} else if (context instanceof Document document) {
|
} else if (context instanceof Document document) {
|
||||||
|
if (document.hasChildNodes()) {
|
||||||
if (args[0].equalsIgnoreCase("modify")) {
|
if (args[0].equalsIgnoreCase("modify")) {
|
||||||
Element elem = traverse(document, args[1]);
|
Element elem = (Element)traverse(document, args[1]);
|
||||||
parseArgs(Arrays.copyOfRange(args, 2, args.length), elem);
|
parseArgs(Arrays.copyOfRange(args, 2, args.length), elem);
|
||||||
} else if (args[0].equalsIgnoreCase("create")) {
|
} else if (args[0].equalsIgnoreCase("create")) {
|
||||||
String newTag = args[1].substring(args[1].lastIndexOf(".")+1);
|
String newTag = args[1].substring(args[1].lastIndexOf(".")+1);
|
||||||
@@ -217,17 +223,14 @@ public class Rizzo {
|
|||||||
traverse(document, args[1].substring(0, args[1].lastIndexOf("."))).appendChild(newElem);
|
traverse(document, args[1].substring(0, args[1].lastIndexOf("."))).appendChild(newElem);
|
||||||
parseArgs(Arrays.copyOfRange(args, 2, args.length), newElem);
|
parseArgs(Arrays.copyOfRange(args, 2, args.length), newElem);
|
||||||
} else if (args[0].equalsIgnoreCase("delete")) {
|
} else if (args[0].equalsIgnoreCase("delete")) {
|
||||||
Element elem = traverse(document, args[1]);
|
Element elem = (Element)traverse(document, args[1]);
|
||||||
elem.getParentNode().removeChild(elem);
|
elem.getParentNode().removeChild(elem);
|
||||||
} else if (args[0].equalsIgnoreCase("merge")) {
|
} else if (args[0].equalsIgnoreCase("merge")) {
|
||||||
// We're basically copying the file context xml command but with another xml document.
|
// We're basically copying the file context xml command but with another xml document.
|
||||||
try {
|
try {
|
||||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
|
||||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||||
|
ReplacingInputStream ris = new ReplacingInputStream(new ReplacingInputStream(new ReplacingInputStream(new FileInputStream(new File(workingDir + args[1])), "\r\n", ""), "&", "&"), "\n", " ");
|
||||||
ReplacingInputStream ris = new ReplacingInputStream(new FileInputStream(new File(workingDir + args[1])), "&", "&");
|
Document outDoc = docBuilder.parse(ris); // throw new FirescriptFormatException("xml", "javax.xml.parsers self-destructed with error:\n" + e.getMessage() + "\nThis usually means you used a bad FSCRIPT, or there was non-standard formatting from the game developer.");
|
||||||
Document outDoc = docBuilder.parse(ris);
|
|
||||||
System.out.println(outDoc.getDocumentElement().toString());
|
|
||||||
|
|
||||||
NamedNodeMap nnm = outDoc.getDocumentElement().getAttributes();
|
NamedNodeMap nnm = outDoc.getDocumentElement().getAttributes();
|
||||||
for (int x = 0; x < nnm.getLength(); x++) {
|
for (int x = 0; x < nnm.getLength(); x++) {
|
||||||
@@ -241,30 +244,73 @@ public class Rizzo {
|
|||||||
document.getDocumentElement().appendChild(importedNode);
|
document.getDocumentElement().appendChild(importedNode);
|
||||||
}
|
}
|
||||||
} catch (SAXException | IOException | ParserConfigurationException ex) {
|
} catch (SAXException | IOException | ParserConfigurationException ex) {
|
||||||
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, "This usually means there's non-standard formatting from the game developer which your FSCRIPT does not account for.", ex);
|
||||||
|
}
|
||||||
|
} else throw new FirescriptFormatException("xml", "command '" + args[0] + "' is unknown or used in inappropriate context");
|
||||||
|
} else {
|
||||||
|
System.out.println("fscript: XML document has no child nodes. Skipping...");
|
||||||
|
parseArgs(Arrays.copyOfRange(args, 1, args.length), document);
|
||||||
}
|
}
|
||||||
} else throw new FirescriptFormatException("xml", "unknown command '" + args[0] + "'");
|
|
||||||
} else if (context instanceof Element element) {
|
} else if (context instanceof Element element) {
|
||||||
if (args[0].equalsIgnoreCase("set")) {
|
if (args[0].equalsIgnoreCase("set")) {
|
||||||
if (args[1].equalsIgnoreCase("attribute"))
|
if (args[1].equalsIgnoreCase("attribute"))
|
||||||
element.setAttribute(args[2], args[3]);
|
// We replace newlines on XML write.
|
||||||
|
element.setAttribute(args[2], args[3].replace("\\n", " "));
|
||||||
else if (args[1].equalsIgnoreCase("value"))
|
else if (args[1].equalsIgnoreCase("value"))
|
||||||
element.setNodeValue(args[2]);
|
element.setNodeValue(args[2]);
|
||||||
} else throw new FirescriptFormatException("");
|
} else if (args[0].equalsIgnoreCase("create")) {
|
||||||
|
String finalTag = args[1];
|
||||||
|
String path = "";
|
||||||
|
if (finalTag.lastIndexOf(".") > 0) {
|
||||||
|
path = args[1].substring(0, finalTag.lastIndexOf("."));
|
||||||
|
finalTag = args[1].substring(finalTag.lastIndexOf(".")+1);
|
||||||
|
}
|
||||||
|
String id = "";
|
||||||
|
String name = "";
|
||||||
|
if (finalTag.contains("#")) {
|
||||||
|
id = finalTag.substring(finalTag.indexOf("#")+1);
|
||||||
|
finalTag = finalTag.substring(0, finalTag.indexOf("#"));
|
||||||
|
} else if (finalTag.contains("$")) {
|
||||||
|
name = finalTag.substring(finalTag.indexOf("$")+1);
|
||||||
|
finalTag = finalTag.substring(0, finalTag.indexOf("$"));
|
||||||
|
}
|
||||||
|
Element finalElem = element.getOwnerDocument().createElement(finalTag);
|
||||||
|
if (id != null && id.length() > 0) finalElem.setAttribute("id", id);
|
||||||
|
if (name != null && name.length() > 0) finalElem.setAttribute("name", name);
|
||||||
|
traverse(element, path).appendChild(finalElem);
|
||||||
|
parseArgs(Arrays.copyOfRange(args, 2, args.length), finalElem);
|
||||||
|
} else if (args[0].equalsIgnoreCase("create-at")) {
|
||||||
|
int index = Integer.parseInt(args[1]);
|
||||||
|
String finalTag = args[2];
|
||||||
|
String id = "";
|
||||||
|
String name = "";
|
||||||
|
if (finalTag.contains("#")) {
|
||||||
|
id = finalTag.substring(finalTag.indexOf("#")+1);
|
||||||
|
finalTag = finalTag.substring(0, finalTag.indexOf("#"));
|
||||||
|
} else if (finalTag.contains("$")) {
|
||||||
|
name = finalTag.substring(finalTag.indexOf("$")+1);
|
||||||
|
finalTag = finalTag.substring(0, finalTag.indexOf("$"));
|
||||||
|
}
|
||||||
|
Element finalElem = element.getOwnerDocument().createElement(finalTag);
|
||||||
|
if (id != null && id.length() > 0) finalElem.setAttribute("id", id);
|
||||||
|
if (name != null && name.length() > 0) finalElem.setAttribute("name", name);
|
||||||
|
element.insertBefore(finalElem, element.getChildNodes().item(index));
|
||||||
|
parseArgs(Arrays.copyOfRange(args, 3, args.length), finalElem);
|
||||||
|
} else throw new FirescriptFormatException("xml", "unknown element command '" + args[0] + "'");
|
||||||
} else throw new FirescriptFormatException("context is unknown");
|
} else throw new FirescriptFormatException("context is unknown");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Element traverse(Document doc, String selector) throws FirescriptFormatException {
|
private Node traverse(Node owner, String selector) throws FirescriptFormatException {
|
||||||
if (selector == null || selector.length() == 0 || doc == null) {
|
if (selector == null || selector.length() == 0 || owner == null) {
|
||||||
return null;
|
return owner;
|
||||||
}
|
}
|
||||||
String[] elems = selector.split("\\.");
|
String[] elems = selector.split("\\.");
|
||||||
Element parent = null;
|
Node parent = owner;
|
||||||
for (String tag : elems) {
|
for (String tag : elems) {
|
||||||
Element newParent = null;
|
Node newParent = null;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (tag.contains("[")) {
|
if (tag.contains("[")) {
|
||||||
index = Integer.parseInt(tag.substring(tag.indexOf("[")+1, tag.lastIndexOf("]")));
|
index = Integer.parseInt(tag.substring(tag.indexOf("[")+1, tag.lastIndexOf("]")));
|
||||||
@@ -276,20 +322,45 @@ public class Rizzo {
|
|||||||
id = tag.substring(tag.indexOf("#")+1);
|
id = tag.substring(tag.indexOf("#")+1);
|
||||||
tag = tag.substring(0, tag.indexOf("#"));
|
tag = tag.substring(0, tag.indexOf("#"));
|
||||||
}
|
}
|
||||||
|
String name = "";
|
||||||
|
if (tag.contains("$")) {
|
||||||
|
name = tag.substring(tag.indexOf("$")+1);
|
||||||
|
tag = tag.substring(0, tag.indexOf("$"));
|
||||||
|
}
|
||||||
if (id.length() > 0) {
|
if (id.length() > 0) {
|
||||||
NodeList ns;
|
NodeList ns;
|
||||||
if (parent != null) ns = parent.getElementsByTagName(tag);
|
if (parent instanceof Document document)
|
||||||
else ns = doc.getElementsByTagName(tag);
|
ns = document.getElementsByTagName(tag);
|
||||||
|
else
|
||||||
|
ns = ((Element)parent).getElementsByTagName(tag);
|
||||||
for (int i = 0; i < ns.getLength(); i++) {
|
for (int i = 0; i < ns.getLength(); i++) {
|
||||||
Node n = ns.item(i);
|
Node n = ns.item(i);
|
||||||
|
if (n.getNodeName().equals("#text")) continue;
|
||||||
if (((Element)n).getAttribute("id").equals(id)) {
|
if (((Element)n).getAttribute("id").equals(id)) {
|
||||||
newParent = (Element)n;
|
newParent = (Element)n;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (name.length() > 0) {
|
||||||
|
NodeList ns;
|
||||||
|
if (parent instanceof Document document)
|
||||||
|
ns = document.getChildNodes();
|
||||||
|
else
|
||||||
|
ns = ((Element)parent).getChildNodes();
|
||||||
|
for (int i = 0; i < ns.getLength(); i++) {
|
||||||
|
Node n = ns.item(i);
|
||||||
|
if (n instanceof Comment) continue;
|
||||||
|
if (n.getNodeName().equals("#text")) continue;
|
||||||
|
if (((Element)n).getAttribute("name").equals(name)) {
|
||||||
|
newParent = (Element)n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (parent != null) newParent = (Element)parent.getElementsByTagName(tag).item(index);
|
if (parent instanceof Document document)
|
||||||
else newParent = (Element)doc.getElementsByTagName(tag).item(index);
|
newParent = document.getElementsByTagName(tag).item(index);
|
||||||
|
else
|
||||||
|
newParent = ((Element)parent).getElementsByTagName(tag).item(index);
|
||||||
}
|
}
|
||||||
if (newParent == null) throw new FirescriptFormatException("xml: selector is invalid");
|
if (newParent == null) throw new FirescriptFormatException("xml: selector is invalid");
|
||||||
else parent = newParent;
|
else parent = newParent;
|
||||||
|
|||||||
@@ -47,18 +47,19 @@ public class Rowlf {
|
|||||||
|
|
||||||
informationText.getDocument().putProperty("filterNewlines", Boolean.FALSE);
|
informationText.getDocument().putProperty("filterNewlines", Boolean.FALSE);
|
||||||
informationText.setHorizontalAlignment(JTextField.CENTER);
|
informationText.setHorizontalAlignment(JTextField.CENTER);
|
||||||
informationText.setText("Created by bonkmaykr, a.k.a. \"Downforce Agent\"\n" +
|
informationText.setText("Created by bonkmaykr & Wirlaburla\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"Special thanks to:\n" +
|
"Special thanks to:\n" +
|
||||||
"ThatOneBonk, for Thallium and for modding help\n" +
|
"ThatOneBonk, ChaCheeChoo, and the AGRF community\n" +
|
||||||
"Wirlaburla, for web hosting and code assistance\n" +
|
"Psygnosis / Studio Liverpool, SCE Europe\n" +
|
||||||
"Psygnosis, for making our favorite game ever\n" +
|
"Yifan Lu & FailOverflow, TheRadziu, NoPayStation\n" +
|
||||||
"and to all the PSVita hackers who made this possible");
|
"and to all the PSVita hackers who made this possible");
|
||||||
informationText.setHighlighter(null);
|
informationText.setHighlighter(null);
|
||||||
informationText.getCaret().setVisible(false);
|
informationText.getCaret().setVisible(false);
|
||||||
informationText.setFocusable(false);
|
informationText.setFocusable(false);
|
||||||
|
|
||||||
versionLabel.setText("Version " + Main.vstr + " (" + Main.vcode + ")");
|
versionLabel.setText(Main.vstr + " (" + Main.vcode + ")");
|
||||||
|
//if (Main.isNightly) {versionLabel.setText(versionLabel.getText() + " built " + Main.dateOfCompile);}
|
||||||
environmentLabel.setText("Running on Java " + System.getProperty("java.version") + " for " + System.getProperty("os.name"));
|
environmentLabel.setText("Running on Java " + System.getProperty("java.version") + " for " + System.getProperty("os.name"));
|
||||||
|
|
||||||
// display window
|
// display window
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
</component>
|
</component>
|
||||||
</children>
|
</children>
|
||||||
</scrollpane>
|
</scrollpane>
|
||||||
<grid id="eb54e" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
<grid id="eb54e" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
<margin top="0" left="0" bottom="0" right="0"/>
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
<children>
|
<children>
|
||||||
<component id="adce7" class="javax.swing.JButton" binding="cancelBtn">
|
<component id="adce7" class="javax.swing.JButton" binding="cancelBtn">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="2" fill="1" indent="0" use-parent-layout="false"/>
|
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="2" fill="1" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<background color="-2271221"/>
|
<background color="-2271221"/>
|
||||||
@@ -67,25 +67,27 @@
|
|||||||
</component>
|
</component>
|
||||||
<hspacer id="8ecbf">
|
<hspacer id="8ecbf">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="0" column="0" row-span="2" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
<grid row="0" column="0" row-span="3" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</hspacer>
|
</hspacer>
|
||||||
<component id="b6c2f" class="javax.swing.JCheckBox" binding="checkAdditive">
|
<component id="b6c2f" class="javax.swing.JCheckBox" binding="checkAdditive">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="10" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<enabled value="false"/>
|
<enabled value="false"/>
|
||||||
|
<focusPainted value="false"/>
|
||||||
<font name="Exo 2"/>
|
<font name="Exo 2"/>
|
||||||
<foreground color="-1"/>
|
<foreground color="-1"/>
|
||||||
<opaque value="false"/>
|
<opaque value="false"/>
|
||||||
<text value="Append to default playlist"/>
|
<text value="Append to default playlist"/>
|
||||||
|
<toolTipText value="Check this box to add your playlist to the existing in-game one instead of overwriting it."/>
|
||||||
<visible value="false"/>
|
<visible value="false"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="a7b02" class="javax.swing.JButton" binding="saveBtn">
|
<component id="a7b02" class="javax.swing.JButton" binding="saveBtn">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="2" fill="1" indent="0" use-parent-layout="false"/>
|
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="2" fill="1" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<background color="-2271221"/>
|
<background color="-2271221"/>
|
||||||
@@ -96,6 +98,21 @@
|
|||||||
<text value="Save"/>
|
<text value="Save"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
|
<component id="2252b" class="javax.swing.JCheckBox" binding="checkNormalize">
|
||||||
|
<constraints>
|
||||||
|
<grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="10" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
|
</constraints>
|
||||||
|
<properties>
|
||||||
|
<enabled value="true"/>
|
||||||
|
<focusPainted value="false"/>
|
||||||
|
<font name="Exo 2"/>
|
||||||
|
<foreground color="-1"/>
|
||||||
|
<opaque value="false"/>
|
||||||
|
<text value="Normalize Volumes"/>
|
||||||
|
<toolTipText value="Prevents sound effects from drowning out the music, but may reduce sound quality. This process is SKIPPED for ATRAC9 files since they are never transcoded!"/>
|
||||||
|
<visible value="true"/>
|
||||||
|
</properties>
|
||||||
|
</component>
|
||||||
</children>
|
</children>
|
||||||
</grid>
|
</grid>
|
||||||
<grid id="cc2" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
<grid id="cc2" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
@@ -187,7 +204,9 @@
|
|||||||
<grid id="568f5" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
<grid id="568f5" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
<margin top="0" left="0" bottom="0" right="0"/>
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||||
|
<maximum-size width="600" height="-1"/>
|
||||||
|
</grid>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<opaque value="false"/>
|
<opaque value="false"/>
|
||||||
|
|||||||
@@ -28,10 +28,7 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
@@ -73,10 +70,12 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
private JCheckBox checkAdditive;
|
private JCheckBox checkAdditive;
|
||||||
private JButton spDeleteBtn;
|
private JButton spDeleteBtn;
|
||||||
private JButton mpDeleteBtn;
|
private JButton mpDeleteBtn;
|
||||||
|
private JCheckBox checkNormalize;
|
||||||
private Scooter progressDialog;
|
private Scooter progressDialog;
|
||||||
|
|
||||||
JFrame parent;
|
JFrame parent;
|
||||||
int curIndex = -1;
|
int curIndex = -1;
|
||||||
|
boolean normalizeVolumes = false;
|
||||||
|
|
||||||
public class AudioTrack {
|
public class AudioTrack {
|
||||||
public File path; // file name
|
public File path; // file name
|
||||||
@@ -85,7 +84,7 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
public long size; // file size in bytes
|
public long size; // file size in bytes
|
||||||
public boolean noConvert;
|
public boolean noConvert;
|
||||||
}
|
}
|
||||||
private static List<AudioTrack> tracklist = new ArrayList<AudioTrack>();
|
private List<AudioTrack> tracklist = new ArrayList<AudioTrack>();
|
||||||
private File sptrack;
|
private File sptrack;
|
||||||
private File mptrack;
|
private File mptrack;
|
||||||
|
|
||||||
@@ -207,12 +206,14 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
if (actionEvent.getSource() == spDeleteBtn) {
|
if (actionEvent.getSource() == spDeleteBtn) {
|
||||||
|
dSTitle.setToolTipText(null);
|
||||||
dSTitle.setText("no track");
|
dSTitle.setText("no track");
|
||||||
dSSize.setText("no size");
|
dSSize.setText("no size");
|
||||||
sptrack = null;
|
sptrack = null;
|
||||||
spDeleteBtn.setVisible(false);
|
spDeleteBtn.setVisible(false);
|
||||||
} else
|
} else
|
||||||
if (actionEvent.getSource() == mpDeleteBtn) {
|
if (actionEvent.getSource() == mpDeleteBtn) {
|
||||||
|
dMTitle.setToolTipText(null);
|
||||||
dMTitle.setText("no track");
|
dMTitle.setText("no track");
|
||||||
dMSize.setText("no size");
|
dMSize.setText("no size");
|
||||||
mptrack = null;
|
mptrack = null;
|
||||||
@@ -270,6 +271,7 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
private void moveUp(int index) {
|
private void moveUp(int index) {
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
Collections.swap(tracklist, index, index - 1);
|
Collections.swap(tracklist, index, index - 1);
|
||||||
|
curIndex--;
|
||||||
InitializeSongListInGUI();
|
InitializeSongListInGUI();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,6 +279,7 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
private void moveDown(int index) {
|
private void moveDown(int index) {
|
||||||
if (index < (tracklist.size() - 1)) {
|
if (index < (tracklist.size() - 1)) {
|
||||||
Collections.swap(tracklist, index, index + 1);
|
Collections.swap(tracklist, index, index + 1);
|
||||||
|
curIndex++;
|
||||||
InitializeSongListInGUI();
|
InitializeSongListInGUI();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -295,9 +298,13 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
String dTitleInList; // avoid editing the actual list
|
String dTitleInList; // avoid editing the actual list
|
||||||
String dArtistInList; // otherwise we cause weird JTextField behavior
|
String dArtistInList; // otherwise we cause weird JTextField behavior
|
||||||
if (tracklist.get(i).title == null || tracklist.get(i).title.isEmpty())
|
if (tracklist.get(i).title == null || tracklist.get(i).title.isEmpty())
|
||||||
{dTitleInList = tracklist.get(i).path.getName();} else {dTitleInList = tracklist.get(i).title;}
|
dTitleInList = tracklist.get(i).path.getName();
|
||||||
|
else
|
||||||
|
dTitleInList = tracklist.get(i).title;
|
||||||
if (tracklist.get(i).artist == null || tracklist.get(i).artist.isEmpty())
|
if (tracklist.get(i).artist == null || tracklist.get(i).artist.isEmpty())
|
||||||
{dArtistInList = "Unknown Artist";} else {dArtistInList = tracklist.get(i).artist;}
|
dArtistInList = "Unknown Artist";
|
||||||
|
else
|
||||||
|
dArtistInList = tracklist.get(i).artist;
|
||||||
contents[i] = dArtistInList + " - " + dTitleInList;
|
contents[i] = dArtistInList + " - " + dTitleInList;
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
@@ -311,13 +318,14 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
JFileChooser fileChooser = new JFileChooser();
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
fileChooser.setMultiSelectionEnabled(multiselect);
|
fileChooser.setMultiSelectionEnabled(multiselect);
|
||||||
fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
|
fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
|
||||||
fileChooser.setFileFilter(new FileNameExtensionFilter("All Compatible Files", "mp3", "ogg", "oga", "opus", "m4a", "3gp", "wav", "wave", "aif", "aiff", "aifc", "flac", "at9"));
|
fileChooser.setFileFilter(new FileNameExtensionFilter("All Compatible Files", "mp3", "ogg", "oga", "opus", "m4a", "3gp", "wav", "wave", "aif", "aiff", "aifc", "flac", "at3", "at9"));
|
||||||
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("MPEG Audio Layer 3", "mp3"));
|
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("MPEG Audio Layer 3", "mp3"));
|
||||||
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Ogg Audio", "ogg", "oga", "opus"));
|
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Ogg Audio", "ogg", "oga", "opus"));
|
||||||
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("AAC or MPEG-4 Audio", "m4a", "3gp"));
|
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("AAC or MPEG-4 Audio", "m4a", "3gp"));
|
||||||
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("IBM/Microsoft WAVE", "wav", "wave"));
|
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("IBM/Microsoft WAVE", "wav", "wave"));
|
||||||
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Apple AIFF", "aif", "aiff", "aifc"));
|
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Apple AIFF", "aif", "aiff", "aifc"));
|
||||||
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Free Lossless Audio Codec", "flac"));
|
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Free Lossless Audio Codec", "flac"));
|
||||||
|
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Sony ATRAC3", "at3"));
|
||||||
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Sony ATRAC9", "at9"));
|
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("Sony ATRAC9", "at9"));
|
||||||
return fileChooser;
|
return fileChooser;
|
||||||
}
|
}
|
||||||
@@ -328,7 +336,8 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
if (result == JFileChooser.APPROVE_OPTION) {
|
if (result == JFileChooser.APPROVE_OPTION) {
|
||||||
File selectedFile = fileChooser.getSelectedFile();
|
File selectedFile = fileChooser.getSelectedFile();
|
||||||
sptrack = selectedFile;
|
sptrack = selectedFile;
|
||||||
dSTitle.setText(selectedFile.getName());
|
dSTitle.setText(selectedFile.getName().substring(0, Math.min(selectedFile.getName().length(), 20)));
|
||||||
|
if (selectedFile.getName().length() > 20) {dSTitle.setToolTipText(selectedFile.getName());}
|
||||||
dSSize.setText(selectedFile.length() + " B");
|
dSSize.setText(selectedFile.length() + " B");
|
||||||
if (selectedFile.length() > 1023) {
|
if (selectedFile.length() > 1023) {
|
||||||
dSSize.setText((selectedFile.length() / 1024) + " KB");
|
dSSize.setText((selectedFile.length() / 1024) + " KB");
|
||||||
@@ -346,8 +355,15 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
if (result == JFileChooser.APPROVE_OPTION) {
|
if (result == JFileChooser.APPROVE_OPTION) {
|
||||||
File selectedFile = fileChooser.getSelectedFile();
|
File selectedFile = fileChooser.getSelectedFile();
|
||||||
mptrack = selectedFile;
|
mptrack = selectedFile;
|
||||||
dMTitle.setText(selectedFile.getName());
|
dMTitle.setText(selectedFile.getName().substring(0, Math.min(selectedFile.getName().length(), 20)));
|
||||||
dMSize.setText((selectedFile.length() / 1000) + "kb");
|
if (selectedFile.getName().length() > 20) {dMTitle.setToolTipText(selectedFile.getName());}
|
||||||
|
dMSize.setText(selectedFile.length() + " B");
|
||||||
|
if (selectedFile.length() > 1023) {
|
||||||
|
dMSize.setText((selectedFile.length() / 1024) + " KB");
|
||||||
|
}
|
||||||
|
if (selectedFile.length() > 1048575) {
|
||||||
|
dMSize.setText((selectedFile.length() / 1048576) + " MB");
|
||||||
|
}
|
||||||
mpDeleteBtn.setVisible(true);
|
mpDeleteBtn.setVisible(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,6 +395,7 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
private void save() {
|
private void save() {
|
||||||
frame.setEnabled(false);
|
frame.setEnabled(false);
|
||||||
frame.setAlwaysOnTop(false);
|
frame.setAlwaysOnTop(false);
|
||||||
|
normalizeVolumes = checkNormalize.isSelected();
|
||||||
Main.deleteDir(new File(System.getProperty("user.home") + "/.firestar/temp/")); // starts with clean temp
|
Main.deleteDir(new File(System.getProperty("user.home") + "/.firestar/temp/")); // starts with clean temp
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
int progressSize = tracklist.size()+(sptrack != null?1:0)+(mptrack != null?1:0)+1; // Accounting for processes
|
int progressSize = tracklist.size()+(sptrack != null?1:0)+(mptrack != null?1:0)+1; // Accounting for processes
|
||||||
@@ -396,7 +413,6 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
PrintStream ps = new PrintStream(fos);
|
PrintStream ps = new PrintStream(fos);
|
||||||
ps.println("fscript 1");
|
ps.println("fscript 1");
|
||||||
ps.println("# AUTOGENERATED BY FIRESTAR");
|
ps.println("# AUTOGENERATED BY FIRESTAR");
|
||||||
new File(Main.inpath + "temp/ffmpeg/").mkdirs();
|
|
||||||
for (int i = 0; i < tracklist.size(); i++) {
|
for (int i = 0; i < tracklist.size(); i++) {
|
||||||
AudioTrack at = tracklist.get(i);
|
AudioTrack at = tracklist.get(i);
|
||||||
String trackno = String.format("%02d", i+1);
|
String trackno = String.format("%02d", i+1);
|
||||||
@@ -418,13 +434,26 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
progressDialog.setText("Encoding track " + (i+1) + " out of " + tracklist.size() + "...");
|
progressDialog.setText("Encoding track " + (i+1) + " out of " + tracklist.size() + "...");
|
||||||
try {
|
try {
|
||||||
System.out.println("Encoding track #" + (i+1) + " \"" + oArtist + " - " + oTitle + "\"...");
|
System.out.println("Encoding track #" + (i+1) + " \"" + oArtist + " - " + oTitle + "\"...");
|
||||||
if (!at.path.getName().endsWith(".wav") && !at.path.getName().endsWith(".wave")) { // convert to WAV first if it's not readable by at9tool yet
|
if (normalizeVolumes) { // normalize tracks
|
||||||
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-i", at.path.getPath(), "ffmpeg/" + at.path.getName() + ".wav"}, Main.inpath + "temp/");
|
new File(Main.inpath + "temp/ffmpeg/").mkdirs();
|
||||||
|
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", at.path.getPath(), "-filter", "loudnorm=linear=true:i=-5.0:lra=7.0:tp=0.0", /* force sample rate to prevent Random Stupid Bullshit™ */"-ar", "44100", "ffmpeg/" + at.path.getName() + "_normalized.wav"}, Main.inpath + "temp/");
|
||||||
|
final Thread ioThread = new Thread() {@Override public void run() {Main.printProcessLogToStdOut(p);}};
|
||||||
|
ioThread.start();
|
||||||
|
p.waitFor();
|
||||||
|
at.path = new File(Main.inpath + "temp/ffmpeg/" + at.path.getName() + "_normalized.wav");
|
||||||
|
} else { // convert to WAV first if it's not readable by at9tool yet
|
||||||
|
new File(Main.inpath + "temp/ffmpeg/").mkdirs();
|
||||||
|
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", at.path.getPath(), "-ar", "44100", "ffmpeg/" + at.path.getName() + ".wav"}, Main.inpath + "temp/");
|
||||||
|
final Thread ioThread = new Thread() {@Override public void run() {Main.printProcessLogToStdOut(p);}};
|
||||||
|
ioThread.start();
|
||||||
p.waitFor();
|
p.waitFor();
|
||||||
at.path = new File(Main.inpath + "temp/ffmpeg/" + at.path.getName() + ".wav");
|
at.path = new File(Main.inpath + "temp/ffmpeg/" + at.path.getName() + ".wav");
|
||||||
}
|
}
|
||||||
Process p = Main.exec(new String[]{Main.inpath + "at9tool.exe", "-e", "-br", "144", at.path.getPath(), "data/audio/music/" + trackno + "/music_stereo.at9"}, Main.inpath + "temp/");
|
Process p = Main.exec(new String[]{Main.inpath + "at9tool.exe", "-e", "-br", "144", at.path.getPath(), "data/audio/music/" + trackno + "/music_stereo.at9"}, Main.inpath + "temp/");
|
||||||
|
final Thread ioThread = new Thread() {@Override public void run() {Main.printProcessLogToStdOut(p);}};
|
||||||
|
ioThread.start();
|
||||||
p.waitFor();
|
p.waitFor();
|
||||||
|
Main.deleteDir(new File(Main.inpath + "temp/ffmpeg/"));
|
||||||
} catch (IOException | InterruptedException ex) {
|
} catch (IOException | InterruptedException ex) {
|
||||||
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
@@ -438,31 +467,31 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
oArtistLine = "";
|
oArtistLine = "";
|
||||||
}
|
}
|
||||||
int i2 = 0;
|
int i2 = 0;
|
||||||
while (i2 < 17 /*17 languages*/) {
|
while (i2 < 15 /*17 languages*/) {
|
||||||
String language = "INTERNAL_ERROR";
|
String language = "INTERNAL_ERROR";
|
||||||
switch (i2) {
|
switch (i2) {
|
||||||
case 0: language = "american"; break;
|
case 0 -> language = "american";
|
||||||
case 1: language = "danish"; break;
|
case 1 -> language = "danish";
|
||||||
case 2: language = "dutch"; break;
|
case 2 -> language = "dutch";
|
||||||
case 3: language = "english"; break;
|
case 3 -> language = "english";
|
||||||
case 4: language = "finnish"; break;
|
case 4 -> language = "finnish";
|
||||||
case 5: language = "french"; break;
|
case 5 -> language = "french";
|
||||||
case 6: language = "german"; break;
|
case 6 -> language = "german";
|
||||||
case 7: language = "italian"; break;
|
case 7 -> language = "italian";
|
||||||
case 8: language = "japanese"; break;
|
case 8 -> language = "japanese";
|
||||||
case 9: language = "korean"; break;
|
case 9 -> language = "norwegian";
|
||||||
case 10: language = "norwegian"; break;
|
case 10 -> language = "polish";
|
||||||
case 11: language = "polish"; break;
|
case 11 -> language = "portuguese";
|
||||||
case 12: language = "portuguese"; break;
|
case 12 -> language = "russian";
|
||||||
case 13: language = "russian"; break;
|
case 13 -> language = "spanish";
|
||||||
case 14: language = "spanish"; break;
|
case 14 -> language = "swedish";
|
||||||
case 15: language = "swedish"; break;
|
default -> {
|
||||||
case 16: language = "traditionalchinese"; break;
|
|
||||||
default:
|
|
||||||
int result = JOptionPane.showConfirmDialog(frame, "Firestar encountered an internal error.\nString 'language' exported to FSCRIPT was blank.", "Fatal Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE);
|
int result = JOptionPane.showConfirmDialog(frame, "Firestar encountered an internal error.\nString 'language' exported to FSCRIPT was blank.", "Fatal Error", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE);
|
||||||
if (result == JOptionPane.OK_OPTION) {System.exit(1);} //user safety
|
if (result == JOptionPane.OK_OPTION) {System.exit(1);} //user safety
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
//case 9: language = "korean"; break;
|
||||||
|
//case 16: language = "traditionalchinese"; break;
|
||||||
ps.println("file \"data/plugins/languages/"+language+"/entries.xml\" xml "+ocmd+" StringTable.entry#MT_"+trackno+" set attribute \"string\" \""+oArtistLine+oTitle.replace("\"", "\\\"")+"\"");
|
ps.println("file \"data/plugins/languages/"+language+"/entries.xml\" xml "+ocmd+" StringTable.entry#MT_"+trackno+" set attribute \"string\" \""+oArtistLine+oTitle.replace("\"", "\\\"")+"\"");
|
||||||
i2++;
|
i2++;
|
||||||
}
|
}
|
||||||
@@ -477,14 +506,27 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
if (sptrack.exists()) {
|
if (sptrack.exists()) {
|
||||||
try {
|
try {
|
||||||
System.out.println("Encoding singleplayer frontend track...");
|
System.out.println("Encoding singleplayer frontend track...");
|
||||||
if (!sptrack.getName().endsWith(".wav") && !sptrack.getName().endsWith(".wave")) { // convert to WAV first if it's not readable by at9tool yet
|
if (normalizeVolumes) { // normalize tracks
|
||||||
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-i", sptrack.getPath(), "ffmpeg/" + sptrack.getName() + ".wav"}, Main.inpath + "temp/");
|
new File(Main.inpath + "temp/ffmpeg/").mkdirs();
|
||||||
|
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", sptrack.getPath(), "-filter", "loudnorm=linear=true:i=-10.0:lra=12.0:tp=-2.0", /* force sample rate to prevent Random Stupid Bullshit™ */"-ar", "44100", "ffmpeg/" + sptrack.getName() + "_normalized.wav"}, Main.inpath + "temp/");
|
||||||
|
final Thread ioThread = new Thread() {@Override public void run() {Main.printProcessLogToStdOut(p);}};
|
||||||
|
ioThread.start();
|
||||||
|
p.waitFor();
|
||||||
|
sptrack = new File(Main.inpath + "temp/ffmpeg/" + sptrack.getName() + "_normalized.wav");
|
||||||
|
} else { // convert to WAV first if it's not readable by at9tool yet
|
||||||
|
new File(Main.inpath + "temp/ffmpeg/").mkdirs();
|
||||||
|
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", sptrack.getPath(), "-ar", "44100", "ffmpeg/" + sptrack.getName() + ".wav"}, Main.inpath + "temp/");
|
||||||
|
final Thread ioThread = new Thread() {@Override public void run() {Main.printProcessLogToStdOut(p);}};
|
||||||
|
ioThread.start();
|
||||||
p.waitFor();
|
p.waitFor();
|
||||||
sptrack = new File(Main.inpath + "temp/ffmpeg/" + sptrack.getName() + ".wav");
|
sptrack = new File(Main.inpath + "temp/ffmpeg/" + sptrack.getName() + ".wav");
|
||||||
}
|
}
|
||||||
new File(Main.inpath + "temp/data/audio/music/FEMusic").mkdirs();
|
new File(Main.inpath + "temp/data/audio/music/FEMusic").mkdirs();
|
||||||
Process p = Main.exec(new String[]{Main.inpath + "at9tool.exe", "-e", "-br", "144", sptrack.getPath(), "data/audio/music/FEMusic/frontend_stereo.at9"}, System.getProperty("user.home") + "/.firestar/temp/");
|
Process p = Main.exec(new String[]{Main.inpath + "at9tool.exe", "-e", "-br", "144", sptrack.getPath(), "data/audio/music/FEMusic/frontend_stereo.at9"}, System.getProperty("user.home") + "/.firestar/temp/");
|
||||||
|
final Thread ioThread = new Thread() {@Override public void run() {Main.printProcessLogToStdOut(p);}};
|
||||||
|
ioThread.start();
|
||||||
p.waitFor();
|
p.waitFor();
|
||||||
|
Main.deleteDir(new File(Main.inpath + "temp/ffmpeg/"));
|
||||||
} catch (IOException | InterruptedException ex) {
|
} catch (IOException | InterruptedException ex) {
|
||||||
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
@@ -497,14 +539,27 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
try {
|
try {
|
||||||
assert(mptrack.exists());
|
assert(mptrack.exists());
|
||||||
System.out.println("Encoding multiplayer frontend track...");
|
System.out.println("Encoding multiplayer frontend track...");
|
||||||
if (!mptrack.getName().endsWith(".wav") && !mptrack.getName().endsWith(".wave")) { // convert to WAV first if it's not readable by at9tool yet
|
if (normalizeVolumes) { // normalize tracks
|
||||||
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-i", mptrack.getPath(), "ffmpeg/" + mptrack.getName() + ".wav"}, Main.inpath + "temp/");
|
new File(Main.inpath + "temp/ffmpeg/").mkdirs();
|
||||||
|
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", mptrack.getPath(), "-filter", "loudnorm=linear=true:i=-10.0:lra=12.0:tp=-2.0", /* force sample rate to prevent Random Stupid Bullshit™ */"-ar", "44100", "ffmpeg/" + mptrack.getName() + "_normalized.wav"}, Main.inpath + "temp/");
|
||||||
|
final Thread ioThread = new Thread() {@Override public void run() {Main.printProcessLogToStdOut(p);}};
|
||||||
|
ioThread.start();
|
||||||
|
p.waitFor();
|
||||||
|
mptrack = new File(Main.inpath + "temp/ffmpeg/" + mptrack.getName() + "_normalized.wav");
|
||||||
|
} else { // convert to WAV first if it's not readable by at9tool yet
|
||||||
|
new File(Main.inpath + "temp/ffmpeg/").mkdirs();
|
||||||
|
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", mptrack.getPath(), "-ar", "44100", "ffmpeg/" + mptrack.getName() + ".wav"}, Main.inpath + "temp/");
|
||||||
|
final Thread ioThread = new Thread() {@Override public void run() {Main.printProcessLogToStdOut(p);}};
|
||||||
|
ioThread.start();
|
||||||
p.waitFor();
|
p.waitFor();
|
||||||
mptrack = new File(Main.inpath + "temp/ffmpeg/" + mptrack.getName() + ".wav");
|
mptrack = new File(Main.inpath + "temp/ffmpeg/" + mptrack.getName() + ".wav");
|
||||||
}
|
}
|
||||||
new File(Main.inpath + "temp/data/audio/music/FEDemoMusic").mkdirs();
|
new File(Main.inpath + "temp/data/audio/music/FEDemoMusic").mkdirs();
|
||||||
Process p = Main.exec(new String[]{Main.inpath + "at9tool.exe", "-e", "-br", "144", mptrack.getPath(), "data/audio/music/FEDemoMusic/frontend_stereo.at9"}, System.getProperty("user.home") + "/.firestar/temp/");
|
Process p = Main.exec(new String[]{Main.inpath + "at9tool.exe", "-e", "-br", "144", mptrack.getPath(), "data/audio/music/FEDemoMusic/frontend_stereo.at9"}, System.getProperty("user.home") + "/.firestar/temp/");
|
||||||
|
final Thread ioThread = new Thread() {@Override public void run() {Main.printProcessLogToStdOut(p);}};
|
||||||
|
ioThread.start();
|
||||||
p.waitFor();
|
p.waitFor();
|
||||||
|
Main.deleteDir(new File(Main.inpath + "temp/ffmpeg/"));
|
||||||
} catch (IOException | InterruptedException ex) {
|
} catch (IOException | InterruptedException ex) {
|
||||||
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
@@ -571,7 +626,6 @@ public class Suggs implements ActionListener, ListSelectionListener {
|
|||||||
|
|
||||||
progressDialog.destroyDialog();
|
progressDialog.destroyDialog();
|
||||||
frame.dispose();
|
frame.dispose();
|
||||||
Main.deleteDir(new File(Main.inpath + "temp/ffmpeg/"));
|
|
||||||
Clifford saveDialog = new Clifford();
|
Clifford saveDialog = new Clifford();
|
||||||
saveDialog.isSoundtrack = true;
|
saveDialog.isSoundtrack = true;
|
||||||
saveDialog.Action(frame, new File(Main.inpath + "temp/"));
|
saveDialog.Action(frame, new File(Main.inpath + "temp/"));
|
||||||
|
|||||||
@@ -90,7 +90,9 @@
|
|||||||
<grid id="b015e" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
<grid id="b015e" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
<margin top="0" left="0" bottom="0" right="0"/>
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="4" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
<grid row="4" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||||
|
<maximum-size width="500" height="-1"/>
|
||||||
|
</grid>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<opaque value="false"/>
|
<opaque value="false"/>
|
||||||
@@ -99,7 +101,7 @@
|
|||||||
<children>
|
<children>
|
||||||
<component id="18770" class="javax.swing.JLabel" binding="fOutpath">
|
<component id="18770" class="javax.swing.JLabel" binding="fOutpath">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<font name="Exo 2"/>
|
<font name="Exo 2"/>
|
||||||
@@ -109,7 +111,7 @@
|
|||||||
</component>
|
</component>
|
||||||
<component id="fa1ee" class="javax.swing.JButton" binding="fOutpathChangebtn">
|
<component id="fa1ee" class="javax.swing.JButton" binding="fOutpathChangebtn">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties>
|
<properties>
|
||||||
<background color="-2271221"/>
|
<background color="-2271221"/>
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class Waldorf implements ActionListener {
|
|||||||
dwnSDKbtn.addActionListener(this);
|
dwnSDKbtn.addActionListener(this);
|
||||||
fOutpathChangebtn.addActionListener(this);
|
fOutpathChangebtn.addActionListener(this);
|
||||||
|
|
||||||
fOutpath.setText(Main.outpath);
|
updateDOutpath(Main.outpath);
|
||||||
checkUpdatesToggle.setSelected(Main.checkUpdates);
|
checkUpdatesToggle.setSelected(Main.checkUpdates);
|
||||||
|
|
||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
@@ -81,6 +81,13 @@ public class Waldorf implements ActionListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateDOutpath(String path) {
|
||||||
|
String s = path;
|
||||||
|
if (s.startsWith(System.getProperty("user.home"))) {s = "~" + s.substring(System.getProperty("user.home").length());}
|
||||||
|
if (s.length() > 50) {s = s.substring(0, Math.min(path.length(), 46)) + "...";fOutpath.setToolTipText(path);} else {fOutpath.setToolTipText(null);}
|
||||||
|
fOutpath.setText(s);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent actionEvent) {
|
public void actionPerformed(ActionEvent actionEvent) {
|
||||||
if (actionEvent.getSource() == cancelbtn) {
|
if (actionEvent.getSource() == cancelbtn) {
|
||||||
@@ -126,6 +133,10 @@ public class Waldorf implements ActionListener {
|
|||||||
JOptionPane.showMessageDialog(frame, "PSARC files purged.", "Delete PSARCs", JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.showMessageDialog(frame, "PSARC files purged.", "Delete PSARCs", JOptionPane.INFORMATION_MESSAGE);
|
||||||
} else
|
} else
|
||||||
if (actionEvent.getSource() == dwnARCbtn) {
|
if (actionEvent.getSource() == dwnARCbtn) {
|
||||||
|
if (!new File(Main.inpath + "pkg2zip.exe").exists() || !new File(Main.inpath + "psvpfsparser.exe").exists()) {
|
||||||
|
JOptionPane.showMessageDialog(frame, "Your decryption tools are missing.\nPlease select \"Get Dependencies\" in the Options menu.", "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
new Bert(invoker.frame);
|
new Bert(invoker.frame);
|
||||||
frame.dispose();
|
frame.dispose();
|
||||||
} else
|
} else
|
||||||
@@ -147,7 +158,7 @@ public class Waldorf implements ActionListener {
|
|||||||
if (result == JFileChooser.APPROVE_OPTION) {
|
if (result == JFileChooser.APPROVE_OPTION) {
|
||||||
if (fileChooser.getSelectedFile().isDirectory()) {
|
if (fileChooser.getSelectedFile().isDirectory()) {
|
||||||
tOutPath = fileChooser.getSelectedFile().getAbsolutePath()+"/";
|
tOutPath = fileChooser.getSelectedFile().getAbsolutePath()+"/";
|
||||||
fOutpath.setText(tOutPath);
|
updateDOutpath(tOutPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 823 B After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 851 B After Width: | Height: | Size: 5.0 KiB |
6942
firestar/src/main/resources/post.fscript
Normal file
BIN
firestar/src/main/resources/splash0.png
Normal file
|
After Width: | Height: | Size: 362 KiB |
BIN
firestar/src/main/resources/splash1.png
Normal file
|
After Width: | Height: | Size: 326 KiB |
BIN
firestar/src/main/resources/splash10.png
Normal file
|
After Width: | Height: | Size: 319 KiB |
BIN
firestar/src/main/resources/splash2.png
Normal file
|
After Width: | Height: | Size: 362 KiB |
BIN
firestar/src/main/resources/splash3.png
Normal file
|
After Width: | Height: | Size: 299 KiB |
BIN
firestar/src/main/resources/splash4.png
Normal file
|
After Width: | Height: | Size: 374 KiB |
BIN
firestar/src/main/resources/splash5.png
Normal file
|
After Width: | Height: | Size: 294 KiB |
BIN
firestar/src/main/resources/splash6.png
Normal file
|
After Width: | Height: | Size: 293 KiB |
BIN
firestar/src/main/resources/splash7.png
Normal file
|
After Width: | Height: | Size: 238 KiB |
BIN
firestar/src/main/resources/splash8.png
Normal file
|
After Width: | Height: | Size: 429 KiB |
BIN
firestar/src/main/resources/splash9.png
Normal file
|
After Width: | Height: | Size: 318 KiB |
1287
firestar/src/main/resources/unused.fscript
Normal file
@@ -1 +1 @@
|
|||||||
netbeans.hint.jdkPlatform=JDK_22__System_
|
netbeans.hint.jdkPlatform=JDK_17__System_
|
||||||
|
|||||||