45 Commits

Author SHA1 Message Date
9155493c0e Remove busted splash 2025-03-11 10:29:28 -05:00
c32d45c63f Update version number 2025-03-11 10:25:16 -05:00
e53933200e Update linker settings 2025-03-10 13:01:59 -05:00
Downforce Agent
8840a193a3 These instructions are wrong. 2025-03-05 23:53:22 -05:00
c9a968d173 Display installed PSArcs in options screen 2025-02-25 19:37:37 -06:00
b1f38400c3 splash fixes 2025-02-23 16:32:46 -06:00
889e99f301 Splash screen 2025-02-22 15:45:26 -06:00
9585f16f11 Allow skipping patch download 2025-02-22 11:20:50 -06:00
f7c4603db1 Update Jenkins build info 2025-02-20 14:06:09 -06:00
9292d8db62 Check for dependencies before opening any menus that require them 2025-02-20 10:39:19 -06:00
b8dbfc9095 FINALLY - implement PSARC partial extraction (in the shittiest way, but it's all we can do right now) - 1.3 is about ready 2025-02-20 10:26:26 -06:00
f07a75276c Read/write requires[] and extracts[] 2025-02-20 09:08:23 -06:00
f336be5a0a enforce compatible sample rate for ATRAC9, stop duplicate conversion, (poorly) steal console output from ffmpeg and at9tool 2024-11-03 15:09:13 -06:00
841f8132bb I forgor 2024-10-04 13:14:19 -05:00
5654fa0b9f Checksum downloaded executables, don't quote download filenames 2024-10-04 13:12:34 -05:00
f21d05d245 sync changes to ide/comment from thinkpad 2024-10-03 15:30:41 -04:00
b5f2aa6925 Fix radios being multi-selectible in Bert 2024-10-03 10:42:08 -04:00
12f01000dd Allow downloading data1 from Bert 2024-09-20 21:33:26 -05:00
168e536068 fix XML parser self-destructing when it tries to get child elements belonging to a developer comment 2024-08-02 18:40:31 -05:00
64230f5eb4 Fix main list flipping itself backwards after a deploy 2024-08-02 18:26:39 -05:00
91a574bb04 Reverse extraction order so that bottom of mod list is lowest priority and vice versa 2024-08-02 17:17:07 -05:00
e877f5eaa6 better error dialog 2024-08-02 17:09:06 -05:00
b3a949fe43 better error dialog 2024-08-02 17:00:29 -05:00
a17f7d1b58 cleanup temporary files if gonzo has crashed or when user closes it 2024-08-02 16:22:48 -05:00
efbf8585d2 prepend exec commands with path (for windows) 2024-08-01 18:12:40 -05:00
3849a765e3 update README.md w/ SOP 2024-08-01 16:43:28 -05:00
2bbf34bf70 Create separate version ID for nightly auto-builds, shorten awkward "Version Release" string, add Apache Commons dependencies 2024-08-01 12:42:21 -05:00
ca36fadad1 Truncate overflowing strings 2024-07-30 15:11:18 -05:00
a75f1ad06c Update compiler instructions to not use gradle wrapper which is incorrect 2024-07-29 18:41:29 -04:00
a54c1ea325 Fix #7 2024-07-28 23:37:55 -05:00
780a7d69b3 Undistribute gradlew, will be moving to jenkins server and avoiding micro$oft BS 2024-07-28 06:35:58 -04:00
8dfed698bb Distribute GradleWrapper with source to allow github actions to function (2) 2024-07-27 12:47:16 -05:00
040adf3b7e Distribute GradleWrapper with source to allow github actions to function 2024-07-27 12:43:56 -05:00
309aaec333 Fixed compilation error on Intellij due to new library 2024-07-27 04:10:09 -05:00
8af95d5287 fix xml ignoring among other rizzo improvements 2024-07-26 21:31:41 -05:00
9950188e0d fix the mess of encodings 2024-07-26 21:05:56 -05:00
3d91ebbbd7 credits newline fix 2024-07-26 00:57:52 -05:00
52dbc56104 please just work 2024-07-26 00:57:52 -05:00
17bbae0d66 take care of autistic wipeout xml handling 2024-07-25 23:26:59 -05:00
4aa017f7ac add build directions to readme 2024-07-25 23:16:53 -05:00
a57e5695a5 please just work 2024-07-25 14:46:10 -05:00
009f406a4b fix colors in Extras menu ingame 2024-07-25 13:04:57 -05:00
2d7e0a1cb0 better scroll behavior in Gonzo 2024-07-25 12:12:24 -05:00
b4b8b1ced5 update credits 2024-07-25 11:55:33 -05:00
7d26ed564e exec FFMPEG and wipe ~/firestar/temp/ffmpeg per-song to avoid filling the disk when processing large playlists 2024-07-25 11:19:11 -05:00
38 changed files with 2218 additions and 1010 deletions

2
.gitignore vendored
View File

@@ -28,6 +28,7 @@ out/
### Mac OS ###
.DS_Store
### Binaries ###
/firestar.zip
/run-linux.sh
/run-win32.bat
@@ -37,3 +38,4 @@ out/
/build/
/.gradle/
/gradle/
!/gradle/wrapper/*

View File

@@ -6,10 +6,14 @@
<element id="file-copy" path="$PROJECT_DIR$/META-INF/MANIFEST.MF" />
</element>
<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="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>
</artifact>
</component>

10
.idea/libraries/apache_commons_io.xml generated Normal file
View 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
View 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
View File

@@ -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">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</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">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</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">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />

View File

@@ -1,47 +1,76 @@
![](https://files.worlio.com/users/bonkmaykr/http/git/embed/firestar.png)
**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)
![](https://files.worlio.com/users/bonkmaykr/http/git/embed/2024-07-12_15-02.png)
# Installation
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:
- **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:
- 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`
- 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.
- 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`
- Arch, EndeavourOS, CachyOS, Steam Deck: `sudo pacman -U firestar-ver-arch.pkg.tar.zst`
- **All Platforms:** Grab the [JAR](https://screwgravity.net/firestar/builds/stable/tetsuo/firestar_1.3_portable.jar) and run it.
# System Requirements
- Windows 8 or newer, Mac OS X 10.14 or older, any modern version of Linux/BSD
- If you have a Mac running 10.15 Catalina or newer, you should use Crossover to run the Windows version of Firestar instead.
- If you have a Mac running 10.15 Catalina or newer, you should use Crossover to run the Windows version of Firestar instead.
- Java 17 or above.
- **Non-Windows systems only**: WINE
- **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.
# 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
## 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.
## Where do I download mods?
There's no #1 place for Firestar mods as of now, but we can give you a few sample mods to test out if you are interested in seeing the program in action:
There's no #1 place for Firestar mods as of now, but we can give you a few sample mods to test out if you are interested in seeing the program in action:
- [XP Rebalance](https://files.worlio.com/users/bonkmaykr/patches/2048/XPhack2.fstar): Reduces the amount of grinding required to level up for players who can't access the online campaign. **Leaderboard safe version!**
- [Pepsi Mod](https://files.worlio.com/users/bonkmaykr/http/reddit/pepsi_agility.fstar): Gives the FEISAR Agility ship a Pepsi makeover.
- [Gold AG-SYS Speed](https://files.worlio.com/users/bonkmaykr/patches/2048/gold3.fstar): Better Than Chrome™
- [Continue?](https://files.worlio.com/users/bonkmaykr/patches/2048/continue.fstar): Allows you to exit the pause menu without taking your thumb off the throttle. By ThatOneBonk
- [HD Skin](https://files.worlio.com/users/bonkmaykr/patches/2048/hd_skin.fstar): Recolors the UI to look like WipEout HD. By ThatOneBonk
- [HD Skin](https://files.worlio.com/users/bonkmaykr/patches/2048/hd_skin.fstar): Recolors the UI to look like WipEout HD. By ThatOneBonk
- [Custom Soundtrack](https://files.catbox.moe/pcvfxj.fstar): A custom playlist I put together. This music is copyrighted, don't play it on stream
## What do I need to make my own mods?
For making your own mods, we recommend grabbing one of the many leaked PS Vita SDKs off of Archive.org since it has many of the tools you will need. I recommend using Photoshop CS5 for textures, since Sony officially provides a texture export plugin for CS5 in their SDK. There is also an included at9tool which can help with replacing sounds and music.
Many things like HUDs, custom translations, and even some game variables are kept in XML format and can be edited in any normal text editor like Microsoft Notepad, GNU Nano, GEdit or KWrite. (Please play nice when you're online.)
For making your own mods, we recommend grabbing one of the many leaked PS Vita SDKs off of Archive.org since it has many of the tools you will need. I recommend using Photoshop CS5 for textures, since Sony officially provides a texture export plugin for CS5 in their SDK. There is also an included at9tool which can help with replacing sounds and music.
Many things like HUDs, custom translations, and even some game variables are kept in XML format and can be edited in any normal text editor like Microsoft Notepad, GNU Nano, GEdit or KWrite. (Please play nice when you're online.)
As for models and custom tracks, we don't have a concrete way of modifying those just yet, but work is being done on that, so stay tuned.
## (Non-Windows) About WINE Compatibility
@@ -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.**
# 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
Firestar is built on top of the following additional software:
- *[WINE](https://www.winehq.org/), for running the below applications across platforms.
@@ -58,20 +102,20 @@ Firestar is built on top of the following additional software:
- [pkg2zip](https://github.com/mmozeiko/pkg2zip) & [psvpfsparser](https://github.com/motoharu-gosuto/psvpfstools), for (legal) asset decryption from Playstation Network.
- [libcurl](https://curl.se/libcurl/), allows psvpfsparser to communicate with Henkaku's F00D server.
- psp2psarc, Sony's proprietary PSARC compression/decompression utility.
- at9tool, Sony's proprietary ATRAC9 codec.
- at9tool, Sony's proprietary ATRAC9 codec.
*_WINE, ffmpeg, and the Java Runtime are pulled as package dependencies on Linux systems._
†_Libraries baked directly into the executable._
†_Libraries baked directly into the executable._
All of these, save for psp2psarc, appear in Tetsuo (1.3) and onwards. The licenses for Sony's psp2psarc and at9tool are polar opposite from Firestar's own GPL, so you should not expect Firestar to be a completely "libre" application (but then again, you're a WipEout player, the free software movement clearly isn't a huge concern). The open source nature of Firestar is provided with the hopes of allowing others to critique, audit, and improve upon the software, not necessarily for idealogical reasons.
All of these, save for psp2psarc, appear in Tetsuo (1.3) and onwards. The licenses for Sony's psp2psarc and at9tool are polar opposite from Firestar's own GPL, so you should not expect Firestar to be a completely "libre" application (but then again, you're a WipEout player, the free software movement clearly isn't a huge concern). The open source nature of Firestar is provided with the hopes of allowing others to critique, audit, and improve upon the software, not necessarily for idealogical reasons.
Ideally, in the future, all of this functionality can be built into Firestar natively without any fancy tricks.
## Why use a leaked Playstation SDK?
Because many third-party programs for opening PSARC files either have no ability to create new ones or are prone to corruption bugs. Using the one made by the developers of the file format is the best option as it's what the game developers would have used. Obviously this creates all kinds of legal grey areas, so I can't distribute Sony's proprietary software next to my code. It's downloaded separately during the setup process.
## Why Java?
Cross-platform support with no hassle, a built-in UI framework, and I don't need to sell my soul like every Electron or React 'Native' developer is doing these days.
Cross-platform support with no hassle, a built-in UI framework, and I don't need to sell my soul like every Electron or React 'Native' developer is doing these days.
## Why the name "Firestar"?
Firestar was a secret track in the original WipEout which you unlocked after beating the game at least once, the mod manager is just named after that. Major versions are named after pilots or tracks. Internal class names are named after Muppets characters as this is the same naming convention that Sony used to codename parts inside the PSVita's SOC.

View File

@@ -18,6 +18,8 @@ dependencies {
implementation group: 'net.lingala.zip4j', name: 'zip4j', version: '2.11.5'
implementation group: 'org.json', name: 'json', version: '20240303'
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'
antTask 'com.jetbrains.intellij.java:java-compiler-ant-tasks:203.7148.30'
@@ -30,14 +32,15 @@ java {
}
jar {
manifest {
attributes(
'Main-Class': 'Main'
)
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
manifest {
attributes(
'Main-Class': 'Main'
)
}
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
application {

View 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>

View 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();
}
}

View File

@@ -63,7 +63,7 @@
<properties>
<font name="Exo 2"/>
<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>
</component>
</children>
@@ -108,7 +108,7 @@
</component>
</children>
</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"/>
<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"/>
@@ -120,55 +120,226 @@
</properties>
<border type="none"/>
<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">
<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>
<properties>
<background color="-15128227"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<horizontalTextPosition value="10"/>
<opaque value="false"/>
<text value="HD Add-On Pack"/>
<verticalTextPosition value="0"/>
</properties>
</component>
<component id="5ed0c" class="javax.swing.JCheckBox" binding="furyCheck">
<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>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<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"/>
<horizontalTextPosition value="11"/>
<selected value="false"/>
<text value="Fury Add-On Pack"/>
<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"/>
<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"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
</children>
</grid>
</children>

View File

@@ -30,10 +30,19 @@ public class Bert implements ActionListener {
private JPanel frameContainer;
private JButton cancelbtn;
private JButton downloadbtn;
private JCheckBox patchCheck;
private JCheckBox baseCheck;
private JRadioButton baseCheck;
private JRadioButton patchCheck1;
private JRadioButton patchCheck2;
private JCheckBox hdCheck;
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 JFrame invoker;
@@ -54,8 +63,17 @@ public class Bert implements ActionListener {
frame.setLocationRelativeTo(parent);
frame.setAlwaysOnTop(true);
radios.add(baseCheck);
radios.add(patchCheck1);
radios.add(patchCheck2);
cancelbtn.addActionListener(this);
downloadbtn.addActionListener(this);
baseCheck.addActionListener(this);
patchCheck1.addActionListener(this);
patchCheck2.addActionListener(this);
refreshChecklist();
frame.setIconImage(Main.windowIcon);
@@ -74,6 +92,9 @@ public class Bert implements ActionListener {
invoker.setEnabled(true);
frame.dispose();
}
if (new File(Main.inpath + "data2.psarc").exists())
skipBaseCheck.setEnabled(true);
}
public boolean reportWhenDownloaded(WilkinsCoffee setup) {
@@ -87,34 +108,80 @@ public class Bert implements ActionListener {
@Override
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) {
invoker.setEnabled(true);
frame.dispose();
} else if (actionEvent.getSource() == downloadbtn) {
ArrayList<Main.ArcTarget> arcs = new ArrayList<Main.ArcTarget>();
ArrayList<Main.ArcKey> keys = new ArrayList<Main.ArcKey>();
if (baseCheck.isSelected()) {
arcs.add(Main.ArcTarget.BASE);
keys.add(Main.ArcKey.BASE);
System.out.println("Begin download of data (Game version 1.0)");
// 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);
keys.add(Main.ArcKey.BASE);
System.out.println("Queued download of data (Game version 1.0)");
}
}
if (patchCheck.isSelected()) {
arcs.add(Main.ArcTarget.LATEST);
keys.add(Main.ArcKey.LATEST);
System.out.println("Begin download of data2 (Game version 1.04)");
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);
keys.add(Main.ArcKey.LATEST);
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()) {
arcs.add(Main.ArcTarget.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()) {
arcs.add(Main.ArcTarget.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()) {
frame.setVisible(false);
JOptionPane.showMessageDialog(invoker, "Select one or more asset packs.", "Error", JOptionPane.ERROR_MESSAGE);
frame.setVisible(true);
return;
}
@@ -132,9 +199,13 @@ public class Bert implements ActionListener {
key = Main.ArcKey.BASE.toString();
arcname = "Base game";
break;
case FIRST :
key = Main.ArcKey.FIRST.toString();
arcname = "Update 1.01";
break;
case LATEST :
key = Main.ArcKey.LATEST.toString();
arcname = "Updates";
arcname = "Update 1.04";
break;
case ADDON_HD :
key = Main.ArcKey.ADDON_HD.toString();
@@ -172,7 +243,7 @@ public class Bert implements ActionListener {
Fozzie popup = new Fozzie();
popup.displayTextOnly("Extracting " + arcname + "...", "Extracting");
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());
OutputStream debugout = new BufferedOutputStream(System.out);
int c;
@@ -200,6 +271,9 @@ public class Bert implements ActionListener {
if (type == Main.ArcTarget.BASE) {
extracted = "app/PCSA00015";
name = "data.psarc";
} else if (type == Main.ArcTarget.FIRST) {
extracted = "patch/PCSA00015";
name = "data1.psarc";
} else if (type == Main.ArcTarget.LATEST) {
extracted = "patch/PCSA00015";
name = "data2.psarc";
@@ -226,7 +300,7 @@ public class Bert implements ActionListener {
popup.setText("<html>Decrypting protected PFS:<br/>" + extracted + "</html>", "Decrypting");
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());
OutputStream debugout = new BufferedOutputStream(System.out);
int c;
@@ -276,4 +350,20 @@ public class Bert implements ActionListener {
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);
}
}

View File

@@ -163,12 +163,15 @@ public class Clifford implements ActionListener {
JOptionPane.showMessageDialog(frame, "Mod name cannot be empty.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
container.put("version", mod.version);
container.put("friendlyName", mod.friendlyName);
container.put("author", mod.author);
container.put("description", mod.description);
container.put("loaderversion", mod.loaderversion);
container.put("game", mod.game);
if (!mod.requires.isEmpty()) container.put("requires", mod.requires);
if (!mod.extracts.isEmpty()) container.put("extracts", mod.extracts);
try {
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();
fileChooser.setFileFilter(new FileNameExtensionFilter("Firestar Mod Package", "fstar"));
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;
try {
zip.addFolder(new File(directory.getAbsolutePath() + "/data"));
@@ -211,21 +216,39 @@ public class Clifford implements ActionListener {
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();
container.put("version", Integer.parseInt(fVersion.getText()));
container.put("friendlyName", fName.getText());
container.put("author", fAuthor.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.
// 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) {
container.put("loaderversion", 1);
if (isSoundtrack) {
ArrayList<boolean[]> requiresTemp = new ArrayList<>();
requiresTemp.add(new boolean[]{false, true, false, false});
requiresTemp.add(new boolean[]{true, false, false, false});
container.put("requires", requiresTemp); // Pull localization files for patching.
}
} else {
container.put("loaderversion", 0);
}

View File

@@ -62,7 +62,7 @@ public class Ernie implements ActionListener {
private JFrame parent;
public Ernie(JFrame parent) {
public Ernie(JFrame parent, boolean isManual) {
this.parent = parent;
frame.setIconImage(Main.windowIcon);
byte[] urlraw = getFile(gitapi+"/releases?draft=false&pre-release=false");
@@ -72,7 +72,9 @@ public class Ernie implements ActionListener {
try {
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"));
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.");
frame.add(frameContainer);
notnowbtn.addActionListener(this);
@@ -97,7 +99,10 @@ public class Ernie implements ActionListener {
}
});
frame.setVisible(true);
} else { System.out.println("Updater: No updates."); }
} else {
System.out.println("Updater: No updates.");
if (isManual) {JOptionPane.showMessageDialog(frame, "There are no updates at this time.", "Check for Updates", JOptionPane.INFORMATION_MESSAGE);}
}
} catch (IOException | JSONException ex) {
Logger.getLogger(Ernie.class.getName()).log(Level.SEVERE, null, ex);
}

View File

@@ -51,7 +51,7 @@ public class Fozzie {
frame.setIconImage(Main.windowIcon);
frame.setVisible(true);
label.setText("Downloading \"" + dname + "\"");
label.setText("Downloading " + dname);
try {
URL fileURL = new URL(url);

View File

@@ -20,16 +20,15 @@ import net.lingala.zip4j.ZipFile;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.text.DefaultCaret;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -77,6 +76,9 @@ public class Gonzo {
frame.setAlwaysOnTop(true);
frame.setVisible(true);
DefaultCaret caret = (DefaultCaret) consoleDisplay.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
File psarcHandle = new File(Main.inpath + "data.psarc");
data0 = psarcHandle.isFile();
psarcHandle = new File(Main.inpath + "data1.psarc");
@@ -104,24 +106,47 @@ public class Gonzo {
}
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
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
List<String> dumpThese = new ArrayList<String>();
if (data0) {dumpThese.add("data.psarc");oArcTarget = "data.psarc";}
if (data1) {dumpThese.add("data1.psarc");oArcTarget = "data1.psarc";}
if (data2) {dumpThese.add("data2.psarc");oArcTarget = "data2.psarc";}
if (dlc1) {dumpThese.add("dlc1.psarc");oArcTarget = "dlc1.psarc";}
if (dlc2) {dumpThese.add("dlc2.psarc");oArcTarget = "dlc2.psarc";}
for (Main.Mod m : modsFlipped) {
if (m.enabled) {
System.out.println(m.friendlyName + " : " + m.requires.toString() + " : " + m.extracts.toString());
for (String r : m.requires) if (!dumpThese.contains(r)) dumpThese.add(r);
}
}
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
for (String s : dumpThese) {
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);
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 = Main.exec(new String[]{"../psp2psarc.exe", "extract", "-y", "../"+s}, System.getProperty("user.home") + "/.firestar/temp/");
Process p;
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() {
@Override
public void run() {
@@ -155,15 +180,41 @@ public class Gonzo {
// overwrite assets with custom ones from each mod and/or perform operations as specified in mod's delete list
// todo: implement RegEx functions after delete.txt
for (Main.Mod m : Main.Mods) {
for (Main.Mod m : modsFlipped) {
if (m.enabled) {
try {
System.out.println("Firestar is extracting " + m.friendlyName + " by " + m.author);
consoleDisplay.append("Firestar is extracting " + m.friendlyName + " by " + m.author + "\n");
new ZipFile(System.getProperty("user.home") + "/.firestar/mods/" + m.path).extractAll(System.getProperty("user.home") + "/.firestar/temp/");
if (!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");
if (fscript.exists()) {
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();
}
@@ -171,6 +222,8 @@ public class Gonzo {
if (new File(System.getProperty("user.home") + "/.firestar/temp/delete.txt").isFile()) {
System.out.println("Firestar is deleting files that conflict with " + m.friendlyName + " by " + m.author);
consoleDisplay.append("Firestar is deleting files that conflict with " + m.friendlyName + " by " + m.author + "\n");
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")));
if (Main.windows) {deleteQueue = new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "\\.firestar\\temp\\delete.txt")));} // might be unnecessary
@@ -195,14 +248,15 @@ public class Gonzo {
}
}
// cleanup so we don't run it again for the next mod unless needed
// this is not necessary but good practice
// cleanup so we don't run it again for the next mod
new File(System.getProperty("user.home") + "/.firestar/temp/delete.txt").delete();
}
} catch (Exception e) {
System.out.println(e.getMessage());
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
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);
}
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
AllowExit();
return;
@@ -216,7 +270,7 @@ public class Gonzo {
} catch (IOException | FirescriptFormatException e) {
System.out.println(e.getMessage());
consoleDisplay.append("CRITICAL FAILURE: " + e.getMessage());
JOptionPane.showMessageDialog(this.frame, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
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;
@@ -260,7 +314,7 @@ public class Gonzo {
try {
System.out.println("Firestar is compiling the final build");
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() {
@Override
public void run() {
@@ -309,7 +363,9 @@ public class Gonzo {
}
try {
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(tmp2);
} catch (Exception e) {
System.out.println("WARNING: Temporary files may not have been properly cleared.\n" + e.getMessage());
consoleDisplay.append("WARNING: Temporary files may not have been properly cleared.\n" + e.getMessage());
@@ -342,6 +398,7 @@ public class Gonzo {
@Override
public void windowClosing(WindowEvent e)
{
Main.deleteDir(new File(System.getProperty("user.home") + "/.firestar/temp/"));
invoker.wrapUpDeployment();
e.getWindow().dispose();
}

View File

@@ -18,12 +18,17 @@
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import org.apache.commons.io.IOUtils;
import org.json.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.List;
import javax.imageio.ImageIO;
@@ -31,11 +36,16 @@ import javax.swing.*;
public class Main {
// 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 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;
// Jenkins Build Information
public static boolean isNightly = false;
public static final String vtagPrevious = "tetsuo-1.3.1";
public static String dateOfCompile = null;
// User Settings
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
@@ -47,6 +57,7 @@ public class Main {
public enum ArcTarget { // install target for 2048, type used by downloader
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"),
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");
@@ -62,6 +73,7 @@ public class Main {
public enum ArcKey { // decryption keys for 2048, type used by downloader
BASE("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
FIRST("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
LATEST("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
ADDON_HD("KO5ifR1dQ+eHBlgi6TI0Bdnv4uNsGG5kYGIR4Ojs7ejuis9/anXfuudVNvzgdu+9z1z+asJojA9uAACgRhTl"),
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 String author; // if null, "Author is unknown."
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.
// TODO: save 'false true false false' in ost gen if necessary (patches change localization)
public List<String> requires = new ArrayList<>();
public List<String> extracts = new ArrayList<>();
}
// Mods
@@ -96,12 +108,26 @@ public class Main {
public static Font fExo2;
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
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") +
"\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" +
"the Free Software Foundation, either version 3 of the License, or\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" +
"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
try {
fExo2 = Font.createFont(Font.TRUETYPE_FONT, Main.class.getResourceAsStream("/exo2.ttf"));
@@ -216,10 +244,25 @@ public class Main {
Main.writeConf();
}
public static boolean downloadDependencies () { // todo: CHECKSUM!!!! THESE ARE EXECUTABLES!!!!!!!!!!! DON'T ALLOW MALWARE!!!!
boolean downloader = new Fozzie().DownloadFile("https://bonkmaykr.worlio.com/http/firestar/firesdk.zip", System.getProperty("user.home") + "/.firestar/", "firesdk.zip");
public static boolean downloadDependencies () {
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;}
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");
try {
sdk.extractAll(System.getProperty("user.home") + "/.firestar/");
@@ -230,12 +273,9 @@ public class Main {
}
sdk.getFile().delete(); // cleanup
JOptionPane.showMessageDialog(null, "All remote dependencies satisfied.", "Download Completed", JOptionPane.INFORMATION_MESSAGE);
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 {
Process p;
@@ -250,4 +290,16 @@ public class Main {
}
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;
}
}
}

View File

@@ -31,8 +31,11 @@ import java.math.RoundingMode;
import java.net.URI;
import java.nio.file.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import net.lingala.zip4j.*;
import org.json.JSONException;
import org.json.JSONObject;
@@ -172,7 +175,7 @@ public class MissPiggy implements ActionListener {
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
if (Main.checkUpdates) { StartErnie(); }
if (Main.checkUpdates) { StartErnie(false); }
frame.setVisible(true);
}
@@ -230,6 +233,16 @@ public class MissPiggy implements ActionListener {
if (metadata.has("loaderversion")) {m.loaderversion = Integer.parseInt(metadata.get("loaderversion").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
Main.Mods.add(m);
} catch (Exception e) {
@@ -300,11 +313,11 @@ public class MissPiggy implements ActionListener {
createSelectionEventListener();
}
private void StartErnie() {
private void StartErnie(boolean isManual) {
new Thread(new Runnable() {
@Override
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();
}
@@ -332,7 +345,11 @@ public class MissPiggy implements ActionListener {
if (actionEvent.getSource() == toolsMenu.getItem(0)) {metaEditorGUI(modList.getSelectedIndex());} 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)) {
try {
@@ -358,7 +375,7 @@ public class MissPiggy implements ActionListener {
JOptionPane.showMessageDialog(frame, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
} 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);}
}
@@ -460,7 +477,6 @@ public class MissPiggy implements ActionListener {
}
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);
if (result == JOptionPane.YES_OPTION) {

View File

@@ -31,7 +31,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
@@ -47,15 +46,14 @@ import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.transform.OutputKeys;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import org.apache.commons.text.StringEscapeUtils;
public class Rizzo {
private final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
private Scanner scanner;
private final int maxVer = 1;
private int ver = 1;
@@ -77,9 +75,9 @@ public class Rizzo {
}
private boolean parseArgs(String[] args, Object context) throws FirescriptFormatException {
System.out.println("Parsing Command: " + Arrays.toString(args));
if (args.length > 0) {
if (context == null) {
System.out.println("Parsing Command: " + Arrays.toString(args));
if (args[0].equalsIgnoreCase("fscript")) {
ver = Integer.parseInt(args[1]); // We'll do shit with this later
if (ver > maxVer) throw new FirescriptFormatException(args[0], "script too new");
@@ -87,9 +85,9 @@ public class Rizzo {
File newCtx = new File(workingDir + args[1]);
System.out.println("Calling new parse: " + Arrays.toString(Arrays.copyOfRange(args, 2, args.length)));
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 {
System.out.println("Using 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("{")) {
System.out.println("New context block: " + context.getClass().getName() + "@" + context.hashCode());
parseScript(context);
@@ -106,7 +104,6 @@ public class Rizzo {
}
} else if (args[0].equalsIgnoreCase("xml")) {
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// Mmmm, love me some INVALID XML corrections.
ReplacingInputStream ris = new ReplacingInputStream(new ReplacingInputStream(new ReplacingInputStream(new FileInputStream(file), "\r\n", ""), "&", "&amp;"), "\n", "&#10;");
@@ -118,16 +115,12 @@ public class Rizzo {
StreamResult result = new StreamResult(new StringWriter());
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);
// Look ma, I'm breaking XML standards!
String xmlString = result.getWriter().toString()
.replace("&amp;", "&")
.replace("&#9;", "\t")
.replace("&#8;", "\b")
.replace("&#10;", "\n")
.replace("&#13;", "\r")
.replace("&#12;", "\f");
String xmlString = StringEscapeUtils.unescapeHtml4(result.getWriter().toString());
try (PrintStream ps = new PrintStream(output)) {
ps.print(xmlString);
}
@@ -135,7 +128,7 @@ public class Rizzo {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, 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")) {
try {
@@ -202,49 +195,62 @@ public class Rizzo {
} catch (FirescriptFormatException | PatchFailedException | IOException 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) {
if (args[0].equalsIgnoreCase("modify")) {
Element elem = (Element)traverse(document, args[1]);
parseArgs(Arrays.copyOfRange(args, 2, args.length), elem);
} else if (args[0].equalsIgnoreCase("create")) {
String newTag = args[1].substring(args[1].lastIndexOf(".")+1);
String newID = "";
if (newTag.contains("#")) {
newID = newTag.substring(newTag.indexOf("#")+1);
newTag = newTag.substring(0, newTag.indexOf("#"));
}
Element newElem = document.createElement(newTag);
if (newID != null && newID.length() > 0) newElem.setAttribute("id", newID);
traverse(document, args[1].substring(0, args[1].lastIndexOf("."))).appendChild(newElem);
parseArgs(Arrays.copyOfRange(args, 2, args.length), newElem);
} else if (args[0].equalsIgnoreCase("delete")) {
Element elem = (Element)traverse(document, args[1]);
elem.getParentNode().removeChild(elem);
} else if (args[0].equalsIgnoreCase("merge")) {
// We're basically copying the file context xml command but with another xml document.
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
ReplacingInputStream ris = new ReplacingInputStream(new ReplacingInputStream(new ReplacingInputStream(new FileInputStream(new File(workingDir + args[1])), "\r\n", ""), "&", "&amp;"), "\n", "&#10;");
Document outDoc = docBuilder.parse(ris);
NamedNodeMap nnm = outDoc.getDocumentElement().getAttributes();
for (int x = 0; x < nnm.getLength(); x++) {
Attr importedNode = (Attr) document.importNode(nnm.item(x), true);
document.getDocumentElement().setAttributeNodeNS(importedNode);
if (document.hasChildNodes()) {
if (args[0].equalsIgnoreCase("modify")) {
Element elem = (Element)traverse(document, args[1]);
parseArgs(Arrays.copyOfRange(args, 2, args.length), elem);
} else if (args[0].equalsIgnoreCase("create")) {
String newTag = args[1].substring(args[1].lastIndexOf(".")+1);
String newID = "";
if (newTag.contains("#")) {
newID = newTag.substring(newTag.indexOf("#")+1);
newTag = newTag.substring(0, newTag.indexOf("#"));
}
Element newElem = document.createElement(newTag);
if (newID != null && newID.length() > 0) newElem.setAttribute("id", newID);
traverse(document, args[1].substring(0, args[1].lastIndexOf("."))).appendChild(newElem);
parseArgs(Arrays.copyOfRange(args, 2, args.length), newElem);
} else if (args[0].equalsIgnoreCase("delete")) {
Element elem = (Element)traverse(document, args[1]);
elem.getParentNode().removeChild(elem);
} else if (args[0].equalsIgnoreCase("merge")) {
// We're basically copying the file context xml command but with another xml document.
try {
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
ReplacingInputStream ris = new ReplacingInputStream(new ReplacingInputStream(new ReplacingInputStream(new FileInputStream(new File(workingDir + args[1])), "\r\n", ""), "&", "&amp;"), "\n", "&#10;");
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.");
NodeList cn = outDoc.getDocumentElement().getChildNodes();
for (int x = 0; x < cn.getLength(); x++) {
Node importedNode = document.importNode(cn.item(x), true);
document.getDocumentElement().appendChild(importedNode);
NamedNodeMap nnm = outDoc.getDocumentElement().getAttributes();
for (int x = 0; x < nnm.getLength(); x++) {
Attr importedNode = (Attr) document.importNode(nnm.item(x), true);
document.getDocumentElement().setAttributeNodeNS(importedNode);
}
NodeList cn = outDoc.getDocumentElement().getChildNodes();
for (int x = 0; x < cn.getLength(); x++) {
Node importedNode = document.importNode(cn.item(x), true);
document.getDocumentElement().appendChild(importedNode);
}
} catch (SAXException | IOException | ParserConfigurationException 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);
}
} catch (SAXException | IOException | ParserConfigurationException ex) {
Logger.getLogger(Rizzo.class.getName()).log(Level.SEVERE, null, ex);
}
} else throw new FirescriptFormatException("xml", "unknown command '" + args[0] + "'");
} 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 if (context instanceof Element element) {
if (args[0].equalsIgnoreCase("set")) {
if (args[1].equalsIgnoreCase("attribute"))
@@ -343,6 +349,7 @@ public class Rizzo {
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;

View File

@@ -47,18 +47,19 @@ public class Rowlf {
informationText.getDocument().putProperty("filterNewlines", Boolean.FALSE);
informationText.setHorizontalAlignment(JTextField.CENTER);
informationText.setText("Created by bonkmaykr, a.k.a. \"Downforce Agent\"\n" +
informationText.setText("Created by bonkmaykr & Wirlaburla\n" +
"\n" +
"Special thanks to:\n" +
"ThatOneBonk, for Thallium and for modding help\n" +
"Wirlaburla, for web hosting and code assistance\n" +
"Psygnosis, for making our favorite game ever\n" +
"ThatOneBonk, ChaCheeChoo, and the AGRF community\n" +
"Psygnosis / Studio Liverpool, SCE Europe\n" +
"Yifan Lu & FailOverflow, TheRadziu, NoPayStation\n" +
"and to all the PSVita hackers who made this possible");
informationText.setHighlighter(null);
informationText.getCaret().setVisible(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"));
// display window

View File

@@ -28,10 +28,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
@@ -209,12 +206,14 @@ public class Suggs implements ActionListener, ListSelectionListener {
}
} else
if (actionEvent.getSource() == spDeleteBtn) {
dSTitle.setToolTipText(null);
dSTitle.setText("no track");
dSSize.setText("no size");
sptrack = null;
spDeleteBtn.setVisible(false);
} else
if (actionEvent.getSource() == mpDeleteBtn) {
dMTitle.setToolTipText(null);
dMTitle.setText("no track");
dMSize.setText("no size");
mptrack = null;
@@ -337,7 +336,8 @@ public class Suggs implements ActionListener, ListSelectionListener {
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
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");
if (selectedFile.length() > 1023) {
dSSize.setText((selectedFile.length() / 1024) + " KB");
@@ -355,7 +355,8 @@ public class Suggs implements ActionListener, ListSelectionListener {
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
mptrack = selectedFile;
dMTitle.setText(selectedFile.getName());
dMTitle.setText(selectedFile.getName().substring(0, Math.min(selectedFile.getName().length(), 20)));
if (selectedFile.getName().length() > 20) {dMTitle.setToolTipText(selectedFile.getName());}
dMSize.setText(selectedFile.length() + " B");
if (selectedFile.length() > 1023) {
dMSize.setText((selectedFile.length() / 1024) + " KB");
@@ -412,7 +413,6 @@ public class Suggs implements ActionListener, ListSelectionListener {
PrintStream ps = new PrintStream(fos);
ps.println("fscript 1");
ps.println("# AUTOGENERATED BY FIRESTAR");
new File(Main.inpath + "temp/ffmpeg/").mkdirs();
for (int i = 0; i < tracklist.size(); i++) {
AudioTrack at = tracklist.get(i);
String trackno = String.format("%02d", i+1);
@@ -434,18 +434,26 @@ public class Suggs implements ActionListener, ListSelectionListener {
progressDialog.setText("Encoding track " + (i+1) + " out of " + tracklist.size() + "...");
try {
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
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", at.path.getPath(), "ffmpeg/" + at.path.getName() + ".wav"}, Main.inpath + "temp/");
if (normalizeVolumes) { // normalize tracks
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();
at.path = new File(Main.inpath + "temp/ffmpeg/" + at.path.getName() + ".wav");
}
if (normalizeVolumes) { // normalize tracks
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/");
p.waitFor();
at.path = new File(Main.inpath + "temp/ffmpeg/" + at.path.getName() + "_normalized.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/");
final Thread ioThread = new Thread() {@Override public void run() {Main.printProcessLogToStdOut(p);}};
ioThread.start();
p.waitFor();
Main.deleteDir(new File(Main.inpath + "temp/ffmpeg/"));
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
@@ -498,19 +506,27 @@ public class Suggs implements ActionListener, ListSelectionListener {
if (sptrack.exists()) {
try {
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
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", sptrack.getPath(), "ffmpeg/" + sptrack.getName() + ".wav"}, Main.inpath + "temp/");
if (normalizeVolumes) { // normalize tracks
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();
sptrack = new File(Main.inpath + "temp/ffmpeg/" + sptrack.getName() + ".wav");
}
if (normalizeVolumes) { // normalize tracks
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/");
p.waitFor();
sptrack = new File(Main.inpath + "temp/ffmpeg/" + sptrack.getName() + "_normalized.wav");
}
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/");
final Thread ioThread = new Thread() {@Override public void run() {Main.printProcessLogToStdOut(p);}};
ioThread.start();
p.waitFor();
Main.deleteDir(new File(Main.inpath + "temp/ffmpeg/"));
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
@@ -523,19 +539,27 @@ public class Suggs implements ActionListener, ListSelectionListener {
try {
assert(mptrack.exists());
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
Process p = Main.exec(new String[]{Main.inpath + "ffmpeg.exe", "-y", "-i", mptrack.getPath(), "ffmpeg/" + mptrack.getName() + ".wav"}, Main.inpath + "temp/");
if (normalizeVolumes) { // normalize tracks
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();
mptrack = new File(Main.inpath + "temp/ffmpeg/" + mptrack.getName() + ".wav");
}
if (normalizeVolumes) { // normalize tracks
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/");
p.waitFor();
mptrack = new File(Main.inpath + "temp/ffmpeg/" + mptrack.getName() + "_normalized.wav");
}
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/");
final Thread ioThread = new Thread() {@Override public void run() {Main.printProcessLogToStdOut(p);}};
ioThread.start();
p.waitFor();
Main.deleteDir(new File(Main.inpath + "temp/ffmpeg/"));
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
@@ -602,7 +626,6 @@ public class Suggs implements ActionListener, ListSelectionListener {
progressDialog.destroyDialog();
frame.dispose();
Main.deleteDir(new File(Main.inpath + "temp/ffmpeg/"));
Clifford saveDialog = new Clifford();
saveDialog.isSoundtrack = true;
saveDialog.Action(frame, new File(Main.inpath + "temp/"));

View File

@@ -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">
<margin top="0" left="0" bottom="0" right="0"/>
<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>
<properties>
<opaque value="false"/>
@@ -99,7 +101,7 @@
<children>
<component id="18770" class="javax.swing.JLabel" binding="fOutpath">
<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>
<properties>
<font name="Exo 2"/>
@@ -109,7 +111,7 @@
</component>
<component id="fa1ee" class="javax.swing.JButton" binding="fOutpathChangebtn">
<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>
<properties>
<background color="-2271221"/>

View File

@@ -67,7 +67,7 @@ public class Waldorf implements ActionListener {
dwnSDKbtn.addActionListener(this);
fOutpathChangebtn.addActionListener(this);
fOutpath.setText(Main.outpath);
updateDOutpath(Main.outpath);
checkUpdatesToggle.setSelected(Main.checkUpdates);
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
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == cancelbtn) {
@@ -126,6 +133,10 @@ public class Waldorf implements ActionListener {
JOptionPane.showMessageDialog(frame, "PSARC files purged.", "Delete PSARCs", JOptionPane.INFORMATION_MESSAGE);
} else
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);
frame.dispose();
} else
@@ -147,7 +158,7 @@ public class Waldorf implements ActionListener {
if (result == JFileChooser.APPROVE_OPTION) {
if (fileChooser.getSelectedFile().isDirectory()) {
tOutPath = fileChooser.getSelectedFile().getAbsolutePath()+"/";
fOutpath.setText(tOutPath);
updateDOutpath(tOutPath);
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 823 B

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 851 B

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -9,13 +9,6 @@ file "data/HandlingStats/ag_systems2048/1/handlingstats.xml" {
set attribute "weight_distribution" "-4.0"
set attribute "width" "5"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "7"
set attribute "handling" "6"
set attribute "shield" "7"
set attribute "speed" "4"
set attribute "thrust" "9"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.3"
set attribute "internalSpeed" "5"
@@ -363,13 +356,6 @@ file "data/HandlingStats/ag_systems2048/2/handlingstats.xml" {
set attribute "weight_distribution" "-4.0"
set attribute "width" "5"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "6"
set attribute "handling" "10"
set attribute "shield" "5"
set attribute "speed" "4"
set attribute "thrust" "8"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.4"
set attribute "internalSpeed" "7"
@@ -717,13 +703,6 @@ file "data/HandlingStats/ag_systems2048/3/handlingstats.xml" {
set attribute "weight_distribution" "-4.0"
set attribute "width" "5"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "6"
set attribute "handling" "8"
set attribute "shield" "3"
set attribute "speed" "8"
set attribute "thrust" "8"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.4"
set attribute "internalSpeed" "7"
@@ -1071,13 +1050,6 @@ file "data/HandlingStats/ag_systems2048/4/handlingstats.xml" {
set attribute "weight_distribution" "-4.0"
set attribute "width" "5"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "6"
set attribute "handling" "10"
set attribute "shield" "6"
set attribute "speed" "4"
set attribute "thrust" "8"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.4"
set attribute "internalSpeed" "7"
@@ -1425,13 +1397,6 @@ file "data/HandlingStats/auricom2048/1/handlingstats.xml" {
set attribute "weight_distribution" "4.0"
set attribute "width" "6.0"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "9"
set attribute "handling" "5"
set attribute "shield" "10"
set attribute "speed" "4"
set attribute "thrust" "7"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.4"
set attribute "internalSpeed" "7"
@@ -1779,13 +1744,6 @@ file "data/HandlingStats/auricom2048/2/handlingstats.xml" {
set attribute "weight_distribution" "4.0"
set attribute "width" "6.0"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "8"
set attribute "handling" "7"
set attribute "shield" "5"
set attribute "speed" "5"
set attribute "thrust" "7"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.4"
set attribute "internalSpeed" "7"
@@ -2133,13 +2091,6 @@ file "data/HandlingStats/auricom2048/3/handlingstats.xml" {
set attribute "weight_distribution" "4.0"
set attribute "width" "6.0"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "7"
set attribute "handling" "5"
set attribute "shield" "6"
set attribute "speed" "9"
set attribute "thrust" "7"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.4"
set attribute "internalSpeed" "7"
@@ -2487,13 +2438,6 @@ file "data/HandlingStats/auricom2048/4/handlingstats.xml" {
set attribute "weight_distribution" "4.0"
set attribute "width" "7"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "9"
set attribute "handling" "5"
set attribute "shield" "5"
set attribute "speed" "4"
set attribute "thrust" "7"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.4"
set attribute "internalSpeed" "7"
@@ -2841,13 +2785,6 @@ file "data/HandlingStats/feisar2048/1/handlingstats.xml" {
set attribute "weight_distribution" "-4.0"
set attribute "width" "5"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "8"
set attribute "handling" "6"
set attribute "shield" "8"
set attribute "speed" "3"
set attribute "thrust" "8"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.4"
set attribute "internalSpeed" "7"
@@ -3195,13 +3132,6 @@ file "data/HandlingStats/feisar2048/2/handlingstats.xml" {
set attribute "weight_distribution" "-4.0"
set attribute "width" "5"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "7"
set attribute "handling" "9"
set attribute "shield" "6"
set attribute "speed" "4"
set attribute "thrust" "8"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.4"
set attribute "internalSpeed" "7"
@@ -3549,13 +3479,6 @@ file "data/HandlingStats/feisar2048/3/handlingstats.xml" {
set attribute "weight_distribution" "-4.0"
set attribute "width" "5"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "6"
set attribute "handling" "7"
set attribute "shield" "4"
set attribute "speed" "8"
set attribute "thrust" "8"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.4"
set attribute "internalSpeed" "7"
@@ -3903,13 +3826,6 @@ file "data/HandlingStats/feisar2048/4/handlingstats.xml" {
set attribute "weight_distribution" "-4.0"
set attribute "width" "5"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "6"
set attribute "handling" "7"
set attribute "shield" "4"
set attribute "speed" "8"
set attribute "thrust" "8"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.4"
set attribute "internalSpeed" "7"
@@ -4257,13 +4173,6 @@ file "data/HandlingStats/piranha2048/1/handlingstats.xml" {
set attribute "weight_distribution" "-4.0"
set attribute "width" "5.0"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "9"
set attribute "handling" "3"
set attribute "shield" "9"
set attribute "speed" "6"
set attribute "thrust" "6"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.3"
set attribute "internalSpeed" "5"
@@ -4611,13 +4520,6 @@ file "data/HandlingStats/piranha2048/2/handlingstats.xml" {
set attribute "weight_distribution" "-4.0"
set attribute "width" "5.0"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "8"
set attribute "handling" "7"
set attribute "shield" "4"
set attribute "speed" "7"
set attribute "thrust" "6"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.3"
set attribute "internalSpeed" "5"
@@ -4965,13 +4867,6 @@ file "data/HandlingStats/piranha2048/3/handlingstats.xml" {
set attribute "weight_distribution" "-4.0"
set attribute "width" "5.0"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "7"
set attribute "handling" "4"
set attribute "shield" "4"
set attribute "speed" "10"
set attribute "thrust" "6"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.3"
set attribute "internalSpeed" "5"
@@ -5319,13 +5214,6 @@ file "data/HandlingStats/piranha2048/4/handlingstats.xml" {
set attribute "weight_distribution" "-4.0"
set attribute "width" "3"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "7"
set attribute "handling" "4"
set attribute "shield" "4"
set attribute "speed" "10"
set attribute "thrust" "6"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.3"
set attribute "internalSpeed" "5"
@@ -5673,13 +5561,6 @@ file "data/HandlingStats/qirex2048/1/handlingstats.xml" {
set attribute "weight_distribution" "4.0"
set attribute "width" "6.0"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "10"
set attribute "handling" "5"
set attribute "shield" "9"
set attribute "speed" "5"
set attribute "thrust" "7"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.3"
set attribute "internalSpeed" "5"
@@ -6027,13 +5908,6 @@ file "data/HandlingStats/qirex2048/2/handlingstats.xml" {
set attribute "weight_distribution" "4.0"
set attribute "width" "6.0"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "9"
set attribute "handling" "7"
set attribute "shield" "8"
set attribute "speed" "6"
set attribute "thrust" "7"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.3"
set attribute "internalSpeed" "5"
@@ -6381,13 +6255,6 @@ file "data/HandlingStats/qirex2048/3/handlingstats.xml" {
set attribute "weight_distribution" "4.0"
set attribute "width" "6.0"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "8"
set attribute "handling" "6"
set attribute "shield" "5"
set attribute "speed" "9"
set attribute "thrust" "7"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.3"
set attribute "internalSpeed" "5"
@@ -6735,13 +6602,6 @@ file "data/HandlingStats/qirex2048/4/handlingstats.xml" {
set attribute "weight_distribution" "4.0"
set attribute "width" "6.0"
}
xml modify Handling.Stats.FE {
set attribute "firepower" "10"
set attribute "handling" "6"
set attribute "shield" "9"
set attribute "speed" "5"
set attribute "thrust" "7"
}
xml modify Handling.Stats.Tilt {
set attribute "internalAmount" "1.3"
set attribute "internalSpeed" "5"
@@ -7079,644 +6939,4 @@ file "data/HandlingStats/qirex2048/4/handlingstats.xml" {
set attribute "gain" "800"
set attribute "turn" "9"
}
}
file "data/plugins/frontend/NEWGUI/Extras_Definition_AS.xml" {
xml modify Screen.Screen$extrasCredits.TouchScroll {
# <Text PushHeight="1"><Values Align="centre" x="460" scale="0.7" color="FEGlobals->Blue2048" font="default" string="Video"></Values></Text>
create-at 16 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.82"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "This build is brought to you by"
}
}
create-at 17 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.82"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "FIRESTAR MOD MANAGER"
}
}
create-at 18 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string ""
}
}
create-at 19 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.7"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Developed by"
}
}
create-at 20 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "bonkmaykr"
}
}
create-at 21 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Wirlaburla"
}
}
create-at 22 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string " "
}
}
create-at 23 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.7"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "With help from"
}
}
create-at 24 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "ThatOneBonk"
}
}
create-at 25 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string " "
}
}
create-at 26 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.7"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Special Thanks to"
}
}
create-at 27 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Yifan Lu"
}
}
create-at 28 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "HellfireWZ"
}
}
create-at 29 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "kanar"
}
}
create-at 30 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "ChaCheeChoo"
}
}
}
}
file "data/plugins/frontend/NEWGUI/Extras_Definition_EU.xml" {
xml modify Screen.Screen$extrasCredits.TouchScroll {
# <Text PushHeight="1"><Values Align="centre" x="460" scale="0.7" color="FEGlobals->Blue2048" font="default" string="Video"></Values></Text>
create-at 16 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.82"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "This build is brought to you by"
}
}
create-at 17 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.82"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "FIRESTAR MOD MANAGER"
}
}
create-at 18 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string ""
}
}
create-at 19 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.7"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Developed by"
}
}
create-at 20 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "bonkmaykr"
}
}
create-at 21 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Wirlaburla"
}
}
create-at 22 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string " "
}
}
create-at 23 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.7"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "With help from"
}
}
create-at 24 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "ThatOneBonk"
}
}
create-at 25 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string " "
}
}
create-at 26 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.7"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Special Thanks to"
}
}
create-at 27 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Yifan Lu"
}
}
create-at 28 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "HellfireWZ"
}
}
create-at 29 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "kanar"
}
}
create-at 30 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "ChaCheeChoo"
}
}
}
}
file "data/plugins/frontend/NEWGUI/Extras_Definition_JP.xml" {
xml modify Screen.Screen$extrasCredits.TouchScroll {
# <Text PushHeight="1"><Values Align="centre" x="460" scale="0.7" color="FEGlobals->Blue2048" font="default" string="Video"></Values></Text>
create-at 16 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.82"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "This build is brought to you by"
}
}
create-at 17 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.82"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "FIRESTAR MOD MANAGER"
}
}
create-at 18 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string ""
}
}
create-at 19 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.7"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Developed by"
}
}
create-at 20 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "bonkmaykr"
}
}
create-at 21 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Wirlaburla"
}
}
create-at 22 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string " "
}
}
create-at 23 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.7"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "With help from"
}
}
create-at 24 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "ThatOneBonk"
}
}
create-at 25 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string " "
}
}
create-at 26 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.7"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Special Thanks to"
}
}
create-at 27 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Yifan Lu"
}
}
create-at 28 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "HellfireWZ"
}
}
create-at 29 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "kanar"
}
}
create-at 30 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "ChaCheeChoo"
}
}
}
}
file "data/plugins/frontend/NEWGUI/Extras_Definition_US.xml" {
xml modify Screen.Screen$extrasCredits.TouchScroll {
# <Text PushHeight="1"><Values Align="centre" x="460" scale="0.7" color="FEGlobals->Blue2048" font="default" string="Video"></Values></Text>
create-at 16 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.82"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "This build is brought to you by"
}
}
create-at 17 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.82"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "FIRESTAR MOD MANAGER"
}
}
create-at 18 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string ""
}
}
create-at 19 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.7"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Developed by"
}
}
create-at 20 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "bonkmaykr"
}
}
create-at 21 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Wirlaburla"
}
}
create-at 22 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string " "
}
}
create-at 23 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.7"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "With help from"
}
}
create-at 24 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "ThatOneBonk"
}
}
create-at 25 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string " "
}
}
create-at 26 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "scale" "0.7"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Special Thanks to"
}
}
create-at 27 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "Yifan Lu"
}
}
create-at 28 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "HellfireWZ"
}
}
create-at 29 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "kanar"
}
}
create-at 30 Text {
set attribute "PushHeight" "1"
create Values {
set attribute "Align" "centre"
set attribute "x" "460"
set attribute "color" "FEGlobals->Blue2048"
set attribute "font" "NEOSANS_BOLD"
set attribute string "ChaCheeChoo"
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
netbeans.hint.jdkPlatform=JDK_22__System_
netbeans.hint.jdkPlatform=JDK_17__System_