64 Commits

Author SHA1 Message Date
55df70130c Goof-proofing 2024-07-18 06:35:50 -05:00
5fbfc33b47 cleanup temp files when disposing clifford 2024-07-18 06:31:45 -05:00
00b8d540b3 fix at9 copying 2024-07-18 06:22:19 -05:00
d88921ed70 use Main.exec, tweak soundtrack gen 2024-07-18 05:09:45 -05:00
785b101245 unfuck code, kill robin, erase evidence 2024-07-16 01:22:40 -05:00
13513987c8 tried to add a feature, fucked up. here, I fucked up other bits of code too. 2024-07-16 01:01:28 -05:00
de0f951ce2 add menu tracks metadata 2024-07-16 00:54:26 -05:00
7e398fbbca Add partial functionality for soundtrack generation 2024-07-14 02:44:22 -05:00
03cc8080e4 improve Options appearance 2024-07-14 02:00:11 -05:00
32a4e45638 prevent automatically scrolling to the bottom when mod details exceed window size 2024-07-13 22:01:02 -05:00
f2786ee08a avoid redundant downloads when setup restart 2024-07-13 18:34:21 -05:00
c53f059bac changed setup icon for psarc dump 2024-07-13 18:25:34 -05:00
583979ab48 reimplement arc cleanup to be manual 2024-07-13 17:51:32 -05:00
2de4167cea whoops 2024-07-13 17:38:42 -05:00
c5be641a20 friendlier download display 2024-07-13 17:37:35 -05:00
317eeedb29 prepare downloader for diff system 2024-07-13 17:25:27 -05:00
f209f5f37a remove todos 2024-07-13 16:25:30 -05:00
2fcf7612a6 Add patching functionality for mods 2024-07-13 02:45:49 -05:00
d473f0ad48 whoops 2024-07-13 00:08:00 -05:00
81e5cbcda3 start ost gen class 2024-07-13 00:03:15 -05:00
3cc78caf62 create ost gen class, change center of windows 2024-07-12 22:40:25 -05:00
5e8227dfaa intellij inspection changes, main cleanup 2024-07-12 17:32:40 -05:00
83efce8f3f added check for updates to options 2024-07-12 17:10:58 -05:00
eccc896e89 Make mod description scrollable 2024-07-12 16:56:06 -05:00
099f2c5a83 options screen updated 2024-07-12 16:54:30 -05:00
84f361641d autoupdater finished 2024-07-12 16:49:04 -05:00
8d2e8204af Update README.md 2024-07-12 16:07:13 -04:00
3a7a694db8 UI consistency overhaul 2024-07-12 15:02:56 -05:00
f863029296 fix premature image swap, fix auto-download not appearing on fresh install 2024-07-12 14:32:38 -05:00
ba7af2e90b wilkins UI adjustments 2024-07-12 14:25:10 -05:00
0699bc3644 rowlf cleanup 2024-07-12 13:50:00 -05:00
aa5d4bb97f fixed incorrect operator making notification appear when it wasn't supposed to 2024-07-12 13:49:37 -05:00
656dbd0975 ernie tweaks 2024-07-12 13:16:27 -05:00
bfcb21769e add update checker (not configurable yet) 2024-07-12 05:57:11 -05:00
4a2a992b04 fixes to kermit rewrite 2024-07-12 05:38:48 -05:00
cd05d82dfc Kermit rewrite (New setup screen) 2024-07-12 05:22:26 -05:00
9cba7fcdb3 Fix DISGUSTING button margins, should have been tweaked back in beta.... 2024-07-12 03:31:15 -05:00
6a1042b0c7 Begin work on kermit rewrite 2024-07-12 03:27:25 -05:00
e0f764b71a fixed settings change not being applied immediately 2024-07-11 22:56:37 -04:00
150210aa5a Update README.md 2024-07-10 03:30:02 -04:00
e06302bb56 Update README.md 2024-07-10 03:20:21 -04:00
e4ac3eb815 Update README.md 2024-07-10 03:17:03 -04:00
a4337bcc2f Update README.md 2024-07-10 03:14:34 -04:00
e0c401182f Fix filename 2024-07-10 01:51:06 -05:00
f615b199a4 Better visual feedback during asset decryption 2024-07-10 01:47:05 -05:00
34c5f17d71 downloader fixes 2024-07-10 01:36:48 -05:00
125fc238b3 Update build.gradle to build JAR with dependencies 2024-07-10 01:36:41 -04:00
bf023781d2 add forceNag for future setup screen rework 2024-07-09 23:39:59 -05:00
1c4f19d84b remove unused debug lines 2024-07-09 23:29:37 -05:00
4d093e7ce8 asset downloader & warn when have no psarcs 2024-07-09 23:28:58 -05:00
d850400f00 gradle artifact fix 2024-07-09 23:28:51 -05:00
9108fd9533 idea: clean up before build 2024-07-09 19:22:12 -05:00
b32b2f45f1 update intellij configuration for gradle 2024-07-09 16:00:12 -05:00
b367721a74 Merge pull request 'Gradle & Proper Resource Streams' (#2) from Wirlaburla/firestar:master into master
Reviewed-on: https://git.worlio.com/bonkmaykr/firestar/pulls/2
2024-07-09 04:09:40 -04:00
4e847fdf30 remove gradle directory from git (not needed) 2024-07-09 03:04:27 -05:00
03a7548983 what the fuck was this? why did it mess with this file? what the fuck? 2024-07-09 03:03:28 -05:00
a7debb3668 return installer directory to its intended location 2024-07-09 03:00:15 -05:00
9de9943f23 use gradle build system instead, replace resources as streams 2024-07-09 02:56:19 -05:00
0008301f83 new downloader gui WIP, auto-download depends on start 2024-07-09 02:10:37 -05:00
d109285657 New program artwork 2024-07-09 00:20:45 -05:00
e4ab20bddb Update README.md 2024-07-05 12:32:39 -04:00
7804a1f260 Update README.md 2024-07-05 12:32:19 -04:00
446bea713e Update README.md 2024-07-04 00:54:10 -04:00
a80362d104 Update README.md 2024-07-04 00:49:35 -04:00
56 changed files with 3678 additions and 236 deletions

6
.gitignore vendored
View File

@@ -31,3 +31,9 @@ out/
/firestar.zip
/run-linux.sh
/run-win32.bat
### Gradle ###
/firestar/build/
/build/
/.gradle/
/gradle/

View File

@@ -1,13 +1,15 @@
<component name="ArtifactManager">
<artifact type="jar" build-on-make="true" name="firestar:jar">
<artifact type="jar" build-on-make="true" name="firestar.jar">
<output-path>$PROJECT_DIR$/out/artifacts/firestar_jar</output-path>
<root id="archive" name="firestar.jar">
<element id="directory" name="META-INF">
<element id="file-copy" path="$PROJECT_DIR$/bin/META-INF/MANIFEST.MF" />
<element id="file-copy" path="$PROJECT_DIR$/META-INF/MANIFEST.MF" />
</element>
<element id="module-output" name="firestar" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/net/lingala/zip4j/zip4j/2.11.5/zip4j-2.11.5.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/json/json/20240303/json-20240303.jar" path-in-jar="/" />
<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" />
</root>
</artifact>
</component>

6
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>

17
.idea/gradle.xml generated Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/firestar" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

View File

@@ -1,8 +1,16 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="ClassInitializerMayBeStatic" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="CommentedOutCode" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="FieldMayBeFinal" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FinalPrivateMethod" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FinalStaticMethod" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyResultOfObjectAllocationIgnored" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyUnusedAssignment" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="StringOperationCanBeSimplified" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreStringConstructor" value="true" />
</inspection_tool>
<inspection_tool class="ThrowablePrintStackTrace" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>

30
.idea/jarRepositories.xml generated Normal file
View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven2" />
<option name="name" value="maven2" />
<option name="url" value="https://cache-redirector.jetbrains.com/intellij-dependencies" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="https://www.jetbrains.com/intellij-repository/releases" />
</remote-repository>
</component>
</project>

View File

@@ -1,10 +0,0 @@
<component name="libraryTable">
<library name="json" type="repository">
<properties maven-id="org.json:json:20240303" />
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/json/json/20240303/json-20240303.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -1,10 +0,0 @@
<component name="libraryTable">
<library name="net.lingala.zip4j" type="repository">
<properties maven-id="net.lingala.zip4j:zip4j:2.11.5" />
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/net/lingala/zip4j/zip4j/2.11.5/zip4j-2.11.5.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

1
.idea/misc.xml generated
View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/firestar.iml" filepath="$PROJECT_DIR$/firestar.iml" />
</modules>
</component>
</project>

6
.idea/uiDesigner.xml generated
View File

@@ -8,9 +8,6 @@
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<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.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
@@ -32,6 +29,9 @@
<property name="text" value="CheckBox" />
</initial-values>
</item>
<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.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>

3
META-INF/MANIFEST.MF Normal file
View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: Main

View File

@@ -1,20 +1,28 @@
![](https://files.worlio.com/users/bonkmaykr/http/git/embed/firestar.png)
Firestar is a mod manager for WipEout 2048 which automatically handles sorting mods by priority and repacking game assets based on selected add-on packs. It runs on a desktop/laptop computer and aims to allow easy installation of mods for users who have only a surface level understanding of hacking the PSVita.
**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.
## 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
- **Windows & Mac:** Grab the Portable ZIP from the [Releases](https://git.worlio.com/bonkmaykr/firestar/releases) page and run the JAR file.
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).
- **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.
# System Requirements
- You will need a computer running Microsoft Windows, or any POSIX-compliant desktop operating system such as Mac OS X, Linux, BSD, or MINIX (Firestar does not run directly on the PSVita). ***Wayland support has not been tested.***
- You will also need the Java Runtime Environment installed, at least version 17 or newer. Non-Windows systems will require WINE to be installed for some functionality.
- Please run Firestar on an EXT or NTFS partition as some of the larger file operations it performs may cause glitches in certain filesystems used on memory cards. Do NOT install Firestar directly to your PSVita's storage.
- 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.
- 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.
# FAQ
## Can I use this on a Vita without enso/HEN?
@@ -22,24 +30,42 @@ No. You need a modded Vita in order to use this. Hacking a Vita is super easy th
## 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:
- [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
- XP Rebalance: As the name suggests. **This mod is on hiatus for a bit while I make a version that's safe for online use.**
- [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. (And yes, you can cheat with these--be careful, and play nice when you're online.)
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.
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
psp2psarc.exe is a Windows-only tool (also like super proprietary... sorry). Firestar can run natively on the system but it needs WINE in order to pack the game assets.
Firestar itself can run natively on the system, but it needs WINE in order to handle the game assets because many of the utilities it runs in the background are for Windows only. If you're curious, a list of these tools is available in the "[Third Party Code](#third-party-code)" section below.
**If you are on Mac OS X you will need an older OS version that is still compatible with 32-bit applications.**
# Developer Commentary
## 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.
- *[ffmpeg](https://ffmpeg.org/), for audio conversion in the OST generator
- †[org.json](https://github.com/stleary/JSON-java), Java library for handling JSON data.
- †[zip4j](https://github.com/srikanth-lingala/zip4j), A Java library for ZIP files
- [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.
*_WINE, ffmpeg, and the Java Runtime are pulled as package dependencies on Linux systems._
†_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.
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.

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="net.lingala.zip4j" level="project" />
<orderEntry type="library" name="json" level="project" />
</component>
</module>

58
firestar/build.gradle Normal file
View File

@@ -0,0 +1,58 @@
plugins {
id 'java'
id 'application'
id 'org.beryx.runtime' version '1.12.5'
}
repositories {
mavenCentral()
maven { url "https://www.jetbrains.com/intellij-repository/releases" }
maven { url "https://cache-redirector.jetbrains.com/intellij-dependencies" }
}
configurations {
antTask
}
dependencies {
implementation group: 'net.lingala.zip4j', name: 'zip4j', version: '2.11.5'
implementation group: 'org.json', name: 'json', version: '20240303'
implementation "io.github.java-diff-utils:java-diff-utils:4.12"
implementation 'com.jetbrains.intellij.java:java-gui-forms-rt:203.7148.30'
antTask 'com.jetbrains.intellij.java:java-compiler-ant-tasks:203.7148.30'
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
jar {
manifest {
attributes(
'Main-Class': 'Main'
)
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
application {
mainClass = 'Main'
}
task compileJava(type: JavaCompile, overwrite: true, dependsOn: configurations.implementation.getTaskDependencyFromProjectDependency(true, 'jar')) {
doLast {
project.sourceSets.main.output.classesDirs.each { project.mkdir(it) }
ant.taskdef name: 'javac2', classname: 'com.intellij.ant.Javac2', classpath: configurations.antTask.asPath
ant.javac2 srcdir: project.sourceSets.main.java.srcDirs.join(':'),
classpath: project.sourceSets.main.compileClasspath.asPath,
destdir: project.sourceSets.main.output.classesDirs[0],
source: sourceCompatibility,
target: targetCompatibility,
includeAntRuntime: false
}
}

View File

@@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="Bert">
<grid id="27dc6" binding="frameContainer" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="25" bottom="10" right="25"/>
<constraints>
<xy x="20" y="20" width="1156" height="400"/>
</constraints>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<grid id="59440" layout-manager="GridLayoutManager" row-count="3" 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="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<grid id="1a1a9" layout-manager="GridLayoutManager" row-count="3" 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="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<component id="783ac" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Select the required asset packs below."/>
</properties>
</component>
<component id="e27cc" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="This will depend on what version of the game you have and what DLC you own."/>
</properties>
</component>
<component id="319fa" class="javax.swing.JLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<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."/>
</properties>
</component>
</children>
</grid>
<grid id="23bd7" 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="2" 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>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<component id="a94bd" class="javax.swing.JButton" binding="cancelbtn">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="2" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Cancel"/>
</properties>
</component>
<component id="9f9b3" class="javax.swing.JButton" binding="downloadbtn">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="2" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Download"/>
</properties>
</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">
<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"/>
</constraints>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
</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"/>
</constraints>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<horizontalTextPosition value="10"/>
<text value="HD Add-On Pack"/>
</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"/>
</constraints>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<horizontalTextPosition value="11"/>
<selected value="false"/>
<text value="Fury Add-On Pack"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
</children>
</grid>
</form>

View File

@@ -0,0 +1,287 @@
/*
* Firestar Mod Manager
* Copyright (C) 2024 bonkmaykr
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
public class Bert implements ActionListener {
BufferedImage windowIcon;
public JFrame frame = new JFrame();
private JPanel frameContainer;
private JButton cancelbtn;
private JButton downloadbtn;
private JCheckBox patchCheck;
private JCheckBox baseCheck;
private JCheckBox hdCheck;
private JCheckBox furyCheck;
private ButtonGroup radios = new ButtonGroup();
private JFrame invoker;
private boolean wilkinsDownloadFinished = false;
public Bert(JFrame parent) {
parent.setEnabled(false);
this.invoker = parent;
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
frame.setSize(600, 300); // 1280 800
frame.setTitle("Download Assets");
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(parent);
frame.setAlwaysOnTop(true);
cancelbtn.addActionListener(this);
downloadbtn.addActionListener(this);
try {
windowIcon = ImageIO.read(Main.class.getResourceAsStream("/titleIcon.png"));
frame.setIconImage(windowIcon);
} catch (IOException e) {
System.out.println("ERROR: Failed to find /resources/titleIcon.png. Window will not have an icon.");
}
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
parent.setEnabled(true);
e.getWindow().dispose();
}
});
if (!new File(Main.inpath + "pkg2zip.exe").exists() || !new File(Main.inpath + "psvpfsparser.exe").exists()) {
JOptionPane.showMessageDialog(frame, "The decryption tool is missing.\nPlease select \"Get Dependencies\" in the Options menu.", "Error", JOptionPane.ERROR_MESSAGE);
invoker.setEnabled(true);
frame.dispose();
}
}
public boolean reportWhenDownloaded(WilkinsCoffee setup) {
while (frame.isActive() || !wilkinsDownloadFinished) {}
if (wilkinsDownloadFinished) { // intellij please shut the everloving FUCK up DON'T do this again or i will skin you alive
return true;
} else {
return false;
}
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
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)");
}
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 (hdCheck.isSelected()) {
arcs.add(Main.ArcTarget.ADDON_HD);
keys.add(Main.ArcKey.ADDON_HD);
System.out.println("Begin 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)");
}
if (arcs.isEmpty()) {
JOptionPane.showMessageDialog(invoker, "Select one or more asset packs.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
frame.dispose();
invoker.setVisible(false);
Thread downloaderPopupThread = new Thread(new Runnable() { // run on separate thread to prevent GUI freezing
@Override
public void run() {
for (Main.ArcTarget type : arcs) {
String key = "";
String arcname = "";
switch (type) {
case BASE :
key = Main.ArcKey.BASE.toString();
arcname = "Base game";
break;
case LATEST :
key = Main.ArcKey.LATEST.toString();
arcname = "Updates";
break;
case ADDON_HD :
key = Main.ArcKey.ADDON_HD.toString();
arcname = "HD Add-On Pack";
break;
case ADDON_HD_FURY :
key = Main.ArcKey.ADDON_HD_FURY.toString();
arcname = "Fury Add-On Pack";
break;
}
if (key.isEmpty()) {
System.out.println("Internal Error: Bert got dementia. Get a programmer!");
JOptionPane.showMessageDialog(invoker, "Internal Error: Bert got dementia. Get a programmer!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
return;
}
// download file
Fozzie downloaderHandler = new Fozzie();
boolean downloader = downloaderHandler.DownloadFile(type.toString(), Main.inpath, "asset.pkg", arcname);
if (!downloader) {
// cleanup
new File(Main.inpath + "asset.pkg").delete();
// restore controls
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
return;
}
// dump contents
System.out.println("Extracting " + arcname);
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);
InputStream debugin = new BufferedInputStream(p.getInputStream());
OutputStream debugout = new BufferedOutputStream(System.out);
int c;
while ((c = debugin.read()) != -1) {
debugout.write(c);
}
debugin.close();
debugout.close();
p.waitFor();
} catch (Exception e) {
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(invoker, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
new File(Main.inpath + "asset.pkg").delete();
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
return;
}
// decrypt
System.out.println("Decrypting asset.pkg");
String extracted;
String name;
if (type == Main.ArcTarget.BASE) {
extracted = "app/PCSA00015";
name = "data.psarc";
} else if (type == Main.ArcTarget.LATEST) {
extracted = "patch/PCSA00015";
name = "data2.psarc";
} else if (type == Main.ArcTarget.ADDON_HD) {
extracted = "addcont/PCSA00015/DLC1W2048PACKAGE";
name = "dlc1.psarc";
} else if (type == Main.ArcTarget.ADDON_HD_FURY) { // this is not "always true" - intellij is actually very dumj
extracted = "addcont/PCSA00015/DLC2W2048PACKAGE";
name = "dlc2.psarc";
} else {
System.out.println("Internal Error: Bert got dementia. Get a programmer!");
JOptionPane.showMessageDialog(invoker, "Internal Error: Bert got dementia. Get a programmer!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
new File(Main.inpath + "asset.pkg").delete();
Main.deleteDir(new File(Main.inpath + "app/"));
Main.deleteDir(new File(Main.inpath + "patch/"));
Main.deleteDir(new File(Main.inpath + "addcont/"));
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
return;
}
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);
InputStream debugin = new BufferedInputStream(p.getInputStream());
OutputStream debugout = new BufferedOutputStream(System.out);
int c;
while ((c = debugin.read()) != -1) {
debugout.write(c);
}
debugin.close();
debugout.close();
p.waitFor();
} catch (Exception e) {
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(invoker, "CRITICAL FAILURE: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
new File(Main.inpath + "asset.pkg").delete();
Main.deleteDir(new File(Main.inpath + "app/"));
Main.deleteDir(new File(Main.inpath + "patch/"));
Main.deleteDir(new File(Main.inpath + "addcont/"));
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
return;
}
popup.setText("Deleting temporary files...", "Cleaning Up");
// stage & cleanup
System.out.println("Cleaning up");
new File(Main.inpath + "asset.pkg").delete();
new File(Main.inpath + "temp/PSP2/" + name).renameTo(new File(Main.inpath + name));
Main.deleteDir(new File(Main.inpath + "app/"));
Main.deleteDir(new File(Main.inpath + "patch/"));
Main.deleteDir(new File(Main.inpath + "addcont/"));
Main.deleteDir(new File(Main.inpath + "temp/"));
popup.destroyDialog();
}
// restore controls
JOptionPane.showMessageDialog(frame, "Assets downloaded successfully.", "Download Complete", JOptionPane.INFORMATION_MESSAGE);
invoker.setEnabled(true);
invoker.setVisible(true);
invoker.toFront();
invoker.repaint();
wilkinsDownloadFinished = true;
}
});
downloaderPopupThread.start();
}
}
}

View File

@@ -1,11 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="Clifford">
<grid id="27dc6" binding="frameContainer" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<margin top="10" left="25" bottom="10" right="25"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<component id="3294c" class="javax.swing.JLabel">
@@ -13,6 +17,8 @@
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Name"/>
</properties>
</component>
@@ -21,6 +27,8 @@
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Author"/>
</properties>
</component>
@@ -45,6 +53,8 @@
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Version"/>
</properties>
</component>
@@ -61,6 +71,11 @@
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Save"/>
</properties>
</component>
@@ -69,6 +84,11 @@
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Cancel"/>
</properties>
</component>
@@ -76,7 +96,11 @@
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<component id="4c6b" class="javax.swing.JTextPane" binding="fDescription">
@@ -90,6 +114,8 @@
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Description"/>
</properties>
</component>

View File

@@ -45,14 +45,39 @@ public class Clifford implements ActionListener {
private JButton savebtn;
private JButton cancelbtn;
MissPiggy invoker;
JFrame invoker;
MissPiggy invokerPig;
boolean isPig = false;
Main.Mod mod;
int index;
File directory;
boolean creating;
public void Action(MissPiggy inv, int modindex) { // Editor
public void Action(MissPiggy inv, int modindex) {
invokerPig = inv;
invoker = invokerPig.frame;
mod = Main.Mods.get(modindex);
index = modindex;
creating = false;
isPig = true;
Action(invoker, modindex);
}
public void Action(MissPiggy inv, File dir) {
invokerPig = inv;
invoker = invokerPig.frame;
directory = dir;
creating = true;
isPig = true;
Action(invoker, dir);
}
public void Action(JFrame inv, int modindex) { // Editor
invoker = inv;
mod = Main.Mods.get(modindex);
index = modindex;
@@ -60,10 +85,10 @@ public class Clifford implements ActionListener {
frame.add(frameContainer);
try {
BufferedImage windowIcon = ImageIO.read(new File(System.getProperty("user.dir") + "/resources/titleIcon.png"));
BufferedImage windowIcon = ImageIO.read(Main.class.getResourceAsStream("/titleIcon.png"));
frame.setIconImage(windowIcon);
} catch (IOException e) {
System.out.println("ERROR: Failed to find /resources/titleIcon.png. Window will not have an icon.");
System.out.println("ERROR: Failed to find resource titleIcon.png. Window will not have an icon.");
}
frame.setSize(600, 300); // 1280 800
frame.setMinimumSize(new Dimension(200,100));
@@ -71,7 +96,7 @@ public class Clifford implements ActionListener {
frame.setResizable(false);
frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setLocationRelativeTo(inv);
frame.setAlwaysOnTop(true);
fName.setText(mod.friendlyName);
@@ -87,13 +112,13 @@ public class Clifford implements ActionListener {
@Override
public void windowClosing(WindowEvent e)
{
invoker.frame.setEnabled(true);
invoker.setEnabled(true);
e.getWindow().dispose();
}
});
}
public void Action(MissPiggy inv, File dir) { // Generator
public void Action(JFrame inv, File dir) { // Generator
invoker = inv;
directory = dir;
creating = true;
@@ -116,7 +141,8 @@ public class Clifford implements ActionListener {
@Override
public void windowClosing(WindowEvent e)
{
invoker.frame.setEnabled(true);
Main.deleteDir(new File(Main.inpath + "temp/")); // soundtrack gen
invoker.setEnabled(true);
e.getWindow().dispose();
}
});
@@ -125,7 +151,8 @@ public class Clifford implements ActionListener {
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == cancelbtn) {
invoker.frame.setEnabled(true);
Main.deleteDir(new File(Main.inpath + "temp/")); // soundtrack gen
invoker.setEnabled(true);
frame.dispose();
} else if (actionEvent.getSource() == savebtn && !creating) {
try {
@@ -158,8 +185,8 @@ public class Clifford implements ActionListener {
}
Main.Mods.set(index, mod);
invoker.frame.setEnabled(true);
invoker.InitializeModListInGUI();
invoker.setEnabled(true);
if (isPig) {invokerPig.InitializeModListInGUI();}
frame.dispose();
} else if (actionEvent.getSource() == savebtn && creating) {
if (fName.getText().isEmpty()) {
@@ -203,7 +230,8 @@ public class Clifford implements ActionListener {
return;
}
JOptionPane.showMessageDialog(frame, "Mod file created", "Success", JOptionPane.INFORMATION_MESSAGE);
invoker.frame.setEnabled(true);
Main.deleteDir(new File(Main.inpath + "temp/")); // soundtrack gen
invoker.setEnabled(true);
frame.dispose();
}
}

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="Ernie">
<grid id="27dc6" binding="frameContainer" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="5" bottom="5" right="5"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties>
<background color="-15128227"/>
<foreground color="-592129"/>
</properties>
<border type="none"/>
<children>
<component id="b5829" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-592129"/>
<text value="A new update for Firestar is available!"/>
</properties>
</component>
<grid id="6bf91" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="5" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
</properties>
<border type="none"/>
<children>
<grid id="61273" layout-manager="GridLayoutManager" row-count="1" 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="2" 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>
<background color="-15128227"/>
</properties>
<border type="none"/>
<children>
<component id="56086" class="javax.swing.JButton" binding="notnowbtn">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="2" indent="0" use-parent-layout="false">
<minimum-size width="150" height="-1"/>
<preferred-size width="150" height="-1"/>
<maximum-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-657921"/>
<text value="No Thanks"/>
</properties>
</component>
<component id="a3535" class="javax.swing.JButton" binding="surebtn">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="2" indent="0" use-parent-layout="false">
<minimum-size width="150" height="-1"/>
<preferred-size width="150" height="-1"/>
<maximum-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-592129"/>
<text value="Open in Browser"/>
</properties>
</component>
<vspacer id="9f407">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
<component id="6acad" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-657921"/>
<text value="If you want to stay on this version,"/>
</properties>
</component>
<component id="a73c6" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-592129"/>
<text value="you can disable this notification in the Options."/>
</properties>
</component>
</children>
</grid>
<scrollpane id="1a774">
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="1efd0" class="javax.swing.JEditorPane" binding="changelogDisplay">
<constraints/>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-592129"/>
</properties>
</component>
</children>
</scrollpane>
</children>
</grid>
</form>

View File

@@ -0,0 +1,198 @@
/*
* Firestar Mod Manager
* Copyright (C) 2024 bonkmaykr
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class Ernie implements ActionListener {
// Base URL for Gitea API
public static final String gitapi = "https://git.worlio.com/api/v1/repos/bonkmaykr/firestar";
public static final String changelog = "https://bonkmaykr.worlio.com/http/firestar/changelog.htm";
private HttpURLConnection httpConn;
private int contentLength;
private InputStream inputStream;
private JFrame frame = new JFrame();
private JPanel frameContainer;
private JEditorPane changelogDisplay;
private JButton notnowbtn;
private JButton surebtn;
public boolean backgroundDone = false;
private BufferedImage windowIcon;
private JFrame parent;
public Ernie(JFrame parent) {
this.parent = parent;
try {
windowIcon = ImageIO.read(Main.class.getResourceAsStream("/titleIcon.png"));
frame.setIconImage(windowIcon);
} catch (IOException e) {
System.out.println("ERROR: Failed to find /resources/titleIcon.png. Window will not have an icon.");
}
byte[] urlraw = getFile(gitapi+"/releases?draft=false&pre-release=false");
if (urlraw.length <= 0) {
JOptionPane.showMessageDialog(frame, "Internal Error: Couldn't check for updates.", "Fatal Error", JOptionPane.ERROR_MESSAGE);
} else {
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)) {
System.out.println("Updater: Your version is out of date.");
frame.add(frameContainer);
notnowbtn.addActionListener(this);
surebtn.addActionListener(this);
changelogDisplay.setEditable(false);
changelogDisplay.setPage(changelog);
changelogDisplay.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE); // makes text smaller than joe biden's windmill if font set manually. wtf??
frame.setTitle("An update is available!");
frame.setSize(450, 400);
frame.setResizable(false);
frame.setLocationRelativeTo(parent);
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
parent.setEnabled(false);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
parent.setEnabled(true);
e.getWindow().dispose();
}
});
frame.setVisible(true);
} else { System.out.println("Updater: No updates."); }
} catch (IOException ex) {
Logger.getLogger(Ernie.class.getName()).log(Level.SEVERE, null, ex);
} catch (JSONException ex) {
Logger.getLogger(Ernie.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == notnowbtn) {
parent.setEnabled(true);
frame.dispose();
} else
if (actionEvent.getSource() == surebtn) {
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
String releasepage = "https://git.worlio.com/bonkmaykr/firestar/releases";
try {
Desktop.getDesktop().browse(new URI(releasepage));
parent.setEnabled(true);
frame.dispose();
} catch (Exception ex) {
JOptionPane.showMessageDialog(frame, "Couldn't open your web browser!\nYou can check out the latest release at the URL below:\n"+releasepage, "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
}
byte[] getFile(String url) {
try {
URL fileURL = new URL(url);
httpConn = (HttpURLConnection) fileURL.openConnection();
int response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
contentLength = httpConn.getContentLength();
inputStream = httpConn.getInputStream();
} else if (response == 404) {
throw new IOException(
"File missing from remote server.");
} else {
throw new IOException(
"Unexpected response; Server replied with " + response);
}
ErnieDownloader ed = new ErnieDownloader(this, url, httpConn.getContentLength());
ed.doInBackground();
while (!backgroundDone) {}
inputStream.close();
httpConn.disconnect();
frame.dispose();
return ed.output;
} catch (MalformedURLException e) {
JOptionPane.showMessageDialog(frame, "Internal Error: URL given to Ernie is not valid.\nGet a programmer!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.dispose();
return new byte[]{};
} catch (Exception e) {
JOptionPane.showMessageDialog(frame, "Error: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.dispose();
return new byte[]{};
}
}
}
class ErnieDownloader extends SwingWorker<Void, Void> {
private static final int BUFFER_SIZE = 4096;
private String downloadURL;
private final Ernie gui;
public byte[] output;
public ErnieDownloader(Ernie gui, String downloadURL, long size) {
this.gui = gui;
this.downloadURL = downloadURL;
}
@Override
protected Void doInBackground() throws Exception {
BufferedInputStream in = new BufferedInputStream(new URL(downloadURL).openStream());
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] data = new byte[16384];
int x;
while ((x = in.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, x);
}
output = buffer.toByteArray();
in.close();
gui.backgroundDone = true;
return null;
}
}

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="Fozzie">
<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="500" height="400"/>
</constraints>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<component id="4913b" class="javax.swing.JProgressBar" binding="progressBar">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="50" height="-1"/>
<maximum-size width="200" height="-1"/>
</grid>
</constraints>
<properties>
<background color="-1"/>
<borderPainted value="false"/>
<foreground color="-2271221"/>
<indeterminate value="false"/>
<stringPainted value="true"/>
<value value="0"/>
</properties>
</component>
<component id="46ede" class="javax.swing.JLabel" binding="label">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Downloading file..."/>
</properties>
</component>
</children>
</grid>
</form>

View File

@@ -0,0 +1,191 @@
/*
* Firestar Mod Manager
* Copyright (C) 2024 bonkmaykr
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Optional;
public class Fozzie {
BufferedImage windowIcon;
private JFrame frame = new JFrame();
public JProgressBar progressBar;
private JPanel frameContainer;
private JLabel label;
private HttpURLConnection httpConn;
private int contentLength;
private InputStream inputStream;
public boolean backgroundDone = false;
boolean DownloadFile(String url, String odir, String oname) {
return DownloadFile(url, odir, oname, oname);
}
boolean DownloadFile(String url, String odir, String oname, String dname) {
frame.add(frameContainer);
frame.setSize(300, 100);
frame.setTitle("Download in Progress");
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
try {
windowIcon = ImageIO.read(Main.class.getResourceAsStream("/titleIcon.png"));
frame.setIconImage(windowIcon);
} catch (IOException e) {
System.out.println("ERROR: Failed to find /resources/titleIcon.png. Window will not have an icon.");
}
frame.setVisible(true);
label.setText("Downloading \"" + dname + "\"");
try {
URL fileURL = new URL(url);
httpConn = (HttpURLConnection) fileURL.openConnection();
int response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
String disposition = httpConn.getHeaderField("Content-Disposition");
String contentType = httpConn.getContentType();
contentLength = httpConn.getContentLength();
inputStream = httpConn.getInputStream();
} else if (response == 404) {
throw new IOException(
"File missing from remote server.");
} else {
throw new IOException(
"Unexpected response; Server replied with " + response);
}
new FozzieDownloader(this, url, odir, oname, httpConn.getContentLength()).doInBackground();
while (!backgroundDone) {}
inputStream.close();
httpConn.disconnect();
frame.dispose();
return true;
} catch (MalformedURLException e) {
JOptionPane.showMessageDialog(frame, "Internal Error: URL given to Fozzie is not valid.\nGet a programmer!", "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.dispose();
return false;
} catch (Exception e) {
JOptionPane.showMessageDialog(frame, "Error: " + e.getMessage(), "Fatal Error", JOptionPane.ERROR_MESSAGE);
frame.dispose();
return false;
}
}
public void displayTextOnly(String text, String title) {
frame.add(frameContainer);
frame.setSize(300, 100);
frame.setTitle(title);
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
try {
windowIcon = ImageIO.read(Main.class.getResourceAsStream("/titleIcon.png"));
frame.setIconImage(windowIcon);
} catch (IOException e) {
System.out.println("ERROR: Failed to find /resources/titleIcon.png. Window will not have an icon.");
}
frame.setVisible(true);
label.setText(text);
progressBar.setVisible(false);
}
public void setText(String text, String title) {
label.setText(text);
frame.setTitle(title);
}
public void destroyDialog() {
frame.setVisible(false);
frame.dispose();
}
public void disconnect() throws IOException {
inputStream.close();
httpConn.disconnect();
}
public int getContentLength() {
return this.contentLength;
}
public InputStream getInputStream() {
return this.inputStream;
}
}
class FozzieDownloader extends SwingWorker<Void, Void> {
private static final int BUFFER_SIZE = 4096;
private String downloadURL;
private String saveDirectory;
private String saveName;
private final Fozzie gui;
private final long completeSize;
public FozzieDownloader(Fozzie gui, String downloadURL, String saveDirectory, String saveName, long size) {
this.gui = gui;
this.downloadURL = downloadURL;
this.saveDirectory = saveDirectory;
this.saveName = saveName;
this.completeSize = size;
}
@Override
protected Void doInBackground() throws Exception {
long downloadedSize = 0;
File downloadLocationDir = new File(saveDirectory);
File downloadLocation = new File(saveDirectory + "/" + saveName);
downloadLocationDir.mkdirs();
if (!downloadLocation.isFile()) {
downloadLocation.createNewFile();
}
BufferedInputStream in = new BufferedInputStream(new URL(downloadURL).openStream());
FileOutputStream fos = new FileOutputStream(saveDirectory + "/" + saveName);
BufferedOutputStream out = new BufferedOutputStream(fos,1024);
byte[] data = new byte[1024];
int x = 0;
while ((x = in.read(data,0,1024))>=0) {
downloadedSize += x;
int progress = (int) ((((double)downloadedSize) / ((double)completeSize)) * 100d);
gui.progressBar.setValue(progress);
out.write(data, 0, x);
}
out.close();
in.close();
gui.backgroundDone = true;
return null;
}
}

View File

@@ -1,23 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="Gonzo">
<grid id="27dc6" binding="frameContainer" 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"/>
<margin top="3" left="3" bottom="3" right="3"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<scrollpane id="6830c" binding="scrollPane">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="line" title="Please wait a few minutes. Progress is shown above." title-justification="2" title-position="5"/>
<properties>
<background color="-15128227"/>
<foreground color="-1"/>
</properties>
<border type="line" title="Please wait a few minutes. Progress is shown above." title-justification="2" title-position="5">
<font name="Exo 2"/>
<title-color color="-1"/>
<color color="-1"/>
</border>
<children>
<component id="491c1" class="javax.swing.JTextArea" binding="consoleDisplay">
<constraints/>
<properties>
<background color="-2271221"/>
<font name="Luxi Mono"/>
<foreground color="-1"/>
<text value=""/>
</properties>
</component>

View File

@@ -16,8 +16,10 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import com.github.difflib.DiffUtils;
import com.github.difflib.UnifiedDiffUtils;
import com.github.difflib.patch.Patch;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.util.FileUtils;
import javax.imageio.ImageIO;
import javax.swing.*;
@@ -35,6 +37,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
public class Gonzo {
JFrame frame = new JFrame();
@@ -56,7 +61,7 @@ public class Gonzo {
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
try {
BufferedImage windowIcon = ImageIO.read(new File(System.getProperty("user.dir") + "/resources/titleIcon.png"));
BufferedImage windowIcon = ImageIO.read(Main.class.getResourceAsStream("/titleIcon.png"));
frame.setIconImage(windowIcon);
} catch (IOException e) {
System.out.println("ERROR: Failed to find /resources/titleIcon.png. Window will not have an icon.");
@@ -67,7 +72,7 @@ public class Gonzo {
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setLocationRelativeTo(inv.frame);
frame.setAlwaysOnTop(true);
frame.setVisible(true);
@@ -115,9 +120,7 @@ public class Gonzo {
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;
if (!Main.windows) {p = Runtime.getRuntime().exec(new String[]{"bash","-c","cd " + System.getProperty("user.home") + "/.firestar/temp/" + ";wine ../psp2psarc.exe extract -y ../" + s});}
else {p = Runtime.getRuntime().exec(new String[]{new String(System.getProperty("user.home") + "\\.firestar\\psp2psarc.exe"), "extract", "-y", "..\\" + s}, null, new File(new String(System.getProperty("user.home") + "/.firestar/temp/").replace("/", "\\")));}
Process p = Main.exec(new String[]{"../psp2psarc.exe", "extract", "-y", "../"+s}, System.getProperty("user.home") + "/.firestar/temp/");
final Thread ioThread = new Thread() {
@Override
public void run() {
@@ -158,10 +161,39 @@ public class Gonzo {
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/");
try (Stream<Path> walkStream = Files.walk(Paths.get(System.getProperty("user.home") + "/.firestar/temp/"))) {
walkStream.filter(p -> p.toFile().isFile()).forEach(f -> {
if (f.toString().endsWith(".patch")) {
System.out.println("Patching " + f.toString() + "...");
consoleDisplay.append("Patching " + f.toString() + "...\n");
String mainFile = f.toString().substring(0, f.toString().length() - 6);
try {
List<String> original = Files.readAllLines(new File(mainFile).toPath());
List<String> patched = Files.readAllLines(f);
Patch<String> patch = UnifiedDiffUtils.parseUnifiedDiff(patched);
List<String> result = DiffUtils.patch(original, patch);
try (FileWriter fileWriter = new FileWriter(mainFile)) {
for (String str : result) {
fileWriter.write(str + "\r\n");
}
}
new File(f.toString()).delete();
} catch (Exception ex) {
Logger.getLogger(Gonzo.class.getName()).log(Level.SEVERE, null, ex);
System.out.println(ex.getMessage());
consoleDisplay.append("CRITICAL FAILURE: " + ex.getMessage());
}
}
});
}
if (new File(System.getProperty("user.home") + "/.firestar/temp/delete.txt").isFile()) {
System.out.println("Firestar is deleting files that conflict with " + m.friendlyName + " by " + m.author);
consoleDisplay.append("Firestar is deleting files that conflict with " + m.friendlyName + " by " + m.author + "\n");
String deleteQueue = new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "/.firestar/temp/delete.txt")));
if (Main.windows) {deleteQueue = new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "\\.firestar\\temp\\delete.txt")));} // might be unnecessary
String[] dQarray = deleteQueue.split("\n");
@@ -238,9 +270,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;
if (!Main.windows) {p = Runtime.getRuntime().exec(new String[]{"bash","-c","cd " + System.getProperty("user.home") + "/.firestar/temp" + ";wine ../psp2psarc.exe create --skip-missing-files -j12 -a -i -y --input-file=list.txt -o " + oArcTarget});}
else {p = Runtime.getRuntime().exec(new String[]{new String(System.getProperty("user.home") + "\\.firestar\\psp2psarc.exe"), "create", "--skip-missing-files", "-j12", "-a", "-i", "-y", "--input-file=list.txt", "-o" + oArcTarget}, null, new File(new String(System.getProperty("user.home") + "/.firestar/temp/").replace("/", "\\")));}
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/");
final Thread ioThread = new Thread() {
@Override
public void run() {
@@ -302,10 +332,7 @@ public class Gonzo {
//ignore
}
TitledBorder titledBorder = BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLACK), "DONE! Close this pop-up to continue.");
titledBorder.setTitlePosition(TitledBorder.BOTTOM);
titledBorder.setTitleJustification(TitledBorder.CENTER);
scrollPane.setBorder(titledBorder);
((TitledBorder)scrollPane.getBorder()).setTitle("DONE! Close this pop-up to continue.");
scrollPane.repaint();
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);

View File

@@ -132,7 +132,11 @@ public class Kermit implements ActionListener {
changePage(Pages.DONE);
break;
case DONE:
new MissPiggy().Action();
if (new File(Main.inpath + "psp2psarc.exe").exists()) { // we may have been here before
new MissPiggy().Action(false);
} else {
new MissPiggy().Action(true);
}
page = Pages.AGREEMENT; //set it here since we're disposing of the entire thing
frame.dispose();

View File

@@ -16,34 +16,68 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import org.json.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.List;
import javax.swing.JOptionPane;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Main {
// Build Information
public static final String vstr = "Release 1.2";
public static final String vcode = "Dekka";
public static final int vint = 0;
public static final String vstr = "Release 1.3";
public static final String vcode = "Tetsuo";
public static final String vtag = "tetsuo-1.3"; // set to dekka-1.1 for testing
public static final int vint = 1;
// User Settings
// TODO: replace with user preference when config i/o is done
// also please double check that outpath is actually valid
public static String outpath = System.getProperty("user.home") + "/.firestar/out/"; //game assets location
public static String inpath = System.getProperty("user.home") + "/.firestar/"; //game assets location
public final static String inpath = System.getProperty("user.home") + "/.firestar/"; //firestar folder -- do not change this
public static boolean repatch; //are we in compat mode?
public static boolean windows; //True = windows
public static int confvint = vint;
public static boolean checkUpdates = true;
//public static String psarc; //sdk location
public enum ArcTarget { // install target for 2048, type used by downloader
BASE("http://zeus.dl.playstation.net/cdn/UP9000/PCSA00015_00/NYEoaBGfiWymSEVZKxoyrKyBFsZNoFqxdyAIpZayZYuLLbCAArYrYXjPNhKCfXcONmhIZzZEeArycSrjiJOuNMWuWsDONUxMIQtMk.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");
private final String value;
ArcTarget(final String value) {this.value = value;}
@Override
public String toString() {
return value;
}
}
public enum ArcKey { // install target for 2048, type used by downloader
BASE("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
LATEST("KO5ifR1dQ+eHBlgi6TI0Bdkf7hng6h8aYmRgYuHkCLQNn/9ufV+01fmzjNSmwuVHnO4dEBuN8cENACqVFcgA"),
ADDON_HD("KO5ifR1dQ+eHBlgi6TI0Bdnv4uNsGG5kYGIR4Ojs7ejuis9/anXfuudVNvzgdu+9z1z+asJojA9uAACgRhTl"),
ADDON_HD_FURY("KO5ifR1dQ+eHBlgi6TI0Bdnv4uNsFG5kYGIR4Ojs7ejuis9/3fydBRm3eCJX7biz/vVTm/2jMT64AQCCYhVy");
private final String value;
ArcKey(final String value) {this.value = value;}
@Override
public String toString() {
return value;
}
}
public class Mod {
public String path; // file name
public int version = 1;
//public int gameversion; //TODO detect a game version and compatibility? // no
public int priority = 0; //unused
public String friendlyName;
public String description = "";
@@ -51,6 +85,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 boolean[] requires = new boolean[]{false, false, false, false}; // 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 'true true false false' in ost gen if neccessary (patches change localization)
}
// Mods
@@ -58,6 +94,7 @@ public class Main {
// UI Global Assets
public static Font fExo2;
public static BufferedImage windowIcon;
public static void main(String[] args) {
// license string
@@ -80,17 +117,24 @@ public class Main {
//begin
// load global assets
try {
fExo2 = Font.createFont(Font.TRUETYPE_FONT, new File(System.getProperty("user.dir") + "/resources/exo2.ttf"));
fExo2 = Font.createFont(Font.TRUETYPE_FONT, Main.class.getResourceAsStream("/exo2.ttf"));
} catch (Exception e) {
System.out.println("Font \"Exo 2\" is missing!");
fExo2 = new Font("Arial", Font.PLAIN, 12);
}
// load global window icon
try {
windowIcon = ImageIO.read(Main.class.getResourceAsStream("/titleIcon.png"));
} catch (IOException e) {
System.out.println("ERROR: Failed to find titleIcon.png. Window will not have an icon.");
}
// check and load configs
File fConf = new File(System.getProperty("user.home") + "/.firestar/firestar.conf");
if (!fConf.isFile()) {
System.out.println("No configuration was found. Starting the initial setup");
new Kermit().setup(fConf); // this is a fresh install, run the OOBE.
new WilkinsCoffee().setup();
} else {
new MissPiggy().Action(); // Quick! Start singing Firework by Katy Perry! (or open the main window i guess...)
}
@@ -103,6 +147,7 @@ public class Main {
container.put("HDpath", "TODO"); // proposed hd/fury support for ps3, will use very simplified Fast Mode due to less difficulty installing
container.put("safemode", repatch);
container.put("isWin32", windows);
container.put("checkUpdates", checkUpdates);
container.put("currentPlaylist", "TODO"); // proposed feature: store separate mod lists in lists/ to load/save later?
try {
@@ -116,25 +161,34 @@ public class Main {
try {
JSONObject container = new JSONObject(new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "/.firestar/firestar.conf"))));
System.out.println(container.toString()); // debug
int confvint = (int) container.get("version"); // used for converting configs between program versions later down the line
confvint = (int) container.get("version"); // used for converting configs between program versions later down the line
outpath = container.get("2048path").toString();
repatch = (boolean) container.get("safemode");
windows = (boolean) container.get("isWin32");
try {
checkUpdates = (boolean) container.get("checkUpdates");
} catch (JSONException e) {
checkUpdates = true;
}
} catch (IOException e) {
System.out.println("ERROR: Failed to load firestar.conf");
System.out.println(e.getMessage());
}
return;
}
public static void loadConf(MissPiggy w){
try {
JSONObject container = new JSONObject(new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "/.firestar/firestar.conf"))));
System.out.println(container.toString()); // debug
int confvint = (int) container.get("version"); // used for converting configs between program versions later down the line
confvint = (int) container.get("version"); // used for converting configs between program versions later down the line
outpath = container.get("2048path").toString();
repatch = (boolean) container.get("safemode");
windows = (boolean) container.get("isWin32");
try {
checkUpdates = (boolean) container.get("checkUpdates");
} catch (JSONException e) {
checkUpdates = true;
}
} catch (Exception e) {
JOptionPane.showMessageDialog(w.frame, "Firestar couldn't load your config file. Tread lightly.\n\n" + e.getMessage(), "Critical Error", JOptionPane.ERROR_MESSAGE);
System.out.println("ERROR: Failed to load firestar.conf");
@@ -153,4 +207,47 @@ public class Main {
}
file.delete();
}
public static void downloadDependenciesBeforeSetVisible(JFrame invoker) {
invoker.setVisible(false);
Main.downloadDependencies();
invoker.setVisible(true);
confvint = vint;
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");
if (!downloader) {return false;}
ZipFile sdk = new ZipFile(System.getProperty("user.home") + "/.firestar/firesdk.zip");
try {
sdk.extractAll(System.getProperty("user.home") + "/.firestar/");
} catch (ZipException e) {
JOptionPane.showMessageDialog(new JFrame(), e.getMessage(), "Critical Error", JOptionPane.ERROR_MESSAGE);
System.out.println(e.getMessage());
return false;
}
sdk.getFile().delete(); // cleanup
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;
String[] pcmd;
if (!Main.windows) {
pcmd = new String[cmd.length + 1];
pcmd[0] = "wine";
System.arraycopy(cmd, 0, pcmd, 1, cmd.length);
p = Runtime.getRuntime().exec(pcmd, null, new File(cwd));
} else {
p = Runtime.getRuntime().exec(cmd, null, new File(cwd.replace("/", "\\")));
}
return p;
}
}

View File

@@ -6,8 +6,8 @@
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties>
<background color="-1"/>
<foreground color="-592129"/>
<background color="-15128227"/>
<foreground color="-15128227"/>
</properties>
<border type="none"/>
<children>
@@ -21,23 +21,39 @@
</grid>
</constraints>
<properties>
<background color="-526337"/>
<foreground color="-592129"/>
<background color="-15128227"/>
<foreground color="-1"/>
</properties>
<border type="line" title="Description"/>
<border type="line" title="Description">
<font name="Exo 2"/>
<title-color color="-1"/>
<color color="-1"/>
</border>
<children>
<component id="a9cee" class="javax.swing.JTextPane" binding="descriptionField">
<scrollpane id="6e7e5" binding="descriptionScroller">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="150" height="50"/>
</grid>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<editable value="false"/>
<focusable value="false"/>
<text value="Select a mod from the list on the right to view more details, or to make changes to your installation."/>
<autoscrolls value="false"/>
<foreground color="-1"/>
<opaque value="false"/>
</properties>
</component>
<border type="empty"/>
<children>
<component id="d55bf" class="javax.swing.JTextPane" binding="descriptionField">
<constraints/>
<properties>
<background color="-15128227"/>
<editable value="false"/>
<focusable value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Select a mod from the list on the right to view more details, or to make changes to your installation."/>
</properties>
</component>
</children>
</scrollpane>
</children>
</grid>
<scrollpane id="ecc63" binding="modListScrollContainer">
@@ -45,17 +61,23 @@
<grid row="0" column="1" row-span="2" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-526337"/>
<foreground color="-526337"/>
<background color="-15128227"/>
<foreground color="-1"/>
</properties>
<border type="line" title="Mods List" title-justification="1" title-position="2">
<font/>
<font name="Exo 2"/>
<title-color color="-1"/>
<color color="-1"/>
</border>
<children>
<component id="d80ff" class="javax.swing.JList" binding="modList">
<constraints/>
<properties>
<foreground color="-16777216"/>
<background color="-15128227"/>
<foreground color="-1"/>
<opaque value="true"/>
<selectionBackground color="-2271221"/>
<selectionForeground color="-1"/>
<valueIsAdjusting value="false"/>
</properties>
<clientProperties>
@@ -65,7 +87,7 @@
</children>
</scrollpane>
<grid id="e1585" binding="actionsContainer" 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="10" bottom="0" right="0"/>
<margin top="0" left="5" bottom="5" right="5"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="10" fill="0" indent="0" use-parent-layout="false">
<minimum-size width="300" height="200"/>
@@ -74,10 +96,14 @@
</grid>
</constraints>
<properties>
<background color="-526337"/>
<foreground color="-657921"/>
<background color="-15128227"/>
<foreground color="-1"/>
</properties>
<border type="line" title="Actions"/>
<border type="line" title="Actions">
<font name="Exo 2"/>
<title-color color="-1"/>
<color color="-1"/>
</border>
<children>
<component id="3cd60" class="javax.swing.JButton" binding="toggleButton" default-binding="true">
<constraints>
@@ -87,10 +113,11 @@
</grid>
</constraints>
<properties>
<background color="-15128227"/>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2" style="1"/>
<foreground color="-657921"/>
<foreground color="-1"/>
<text value="Toggle"/>
</properties>
</component>
@@ -102,10 +129,11 @@
</grid>
</constraints>
<properties>
<background color="-15128227"/>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2" style="1"/>
<foreground color="-657921"/>
<foreground color="-1"/>
<text value="Move Up"/>
</properties>
</component>
@@ -119,10 +147,11 @@
</constraints>
<properties>
<alignmentX value="0.0"/>
<background color="-15128227"/>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2" style="1"/>
<foreground color="-657921"/>
<foreground color="-1"/>
<text value="Delete"/>
</properties>
</component>
@@ -135,10 +164,11 @@
</grid>
</constraints>
<properties>
<background color="-15128227"/>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2" style="1"/>
<foreground color="-592129"/>
<foreground color="-1"/>
<text value="Move Down"/>
</properties>
</component>
@@ -149,10 +179,11 @@
</grid>
</constraints>
<properties>
<background color="-15128227"/>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2" style="1"/>
<foreground color="-592129"/>
<foreground color="-1"/>
<text value="Options"/>
</properties>
</component>
@@ -163,10 +194,11 @@
</grid>
</constraints>
<properties>
<background color="-15128227"/>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2" style="1"/>
<foreground color="-526337"/>
<foreground color="-1"/>
<text value="Import"/>
</properties>
</component>
@@ -178,10 +210,11 @@
</grid>
</constraints>
<properties>
<background color="-15128227"/>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2" style="1"/>
<foreground color="-657921"/>
<foreground color="-1"/>
<text value="Deploy"/>
</properties>
</component>

View File

@@ -20,6 +20,7 @@ import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.DefaultCaret;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -71,6 +72,7 @@ public class MissPiggy implements ActionListener {
private JButton importButton;
private JButton deployButton;
private JTextPane descriptionField;
private JScrollPane descriptionScroller;
//private int selectedItem;
@@ -79,8 +81,12 @@ public class MissPiggy implements ActionListener {
public boolean listenersAlreadySet = false; // was written to troubleshoot a bug but this wasn't actually the cause
public void Action() {
Action(false);
}
// Initialize the main window
public void Action(/*Main entryPoint*/) {
public void Action(boolean forceNag) {
System.out.println("Main window created");
System.out.println("Loading program configuration");
Main.loadConf(this);
@@ -109,6 +115,7 @@ public class MissPiggy implements ActionListener {
helpMenu.add(new JMenuItem("Source Code")); //replace with Website 'screwgravity.net' and 'Issue Tracker' gitea later
helpMenu.add(new JMenuItem("License"));
helpMenu.add(new JSeparator());
helpMenu.add(new JMenuItem("Check for Updates"));
helpMenu.add(new JMenuItem("About Firestar"));
menuBar.add(fileMenu);
@@ -134,6 +141,7 @@ public class MissPiggy implements ActionListener {
helpMenu.getItem(2).addActionListener(this);
helpMenu.getItem(3).addActionListener(this);
helpMenu.getItem(5).addActionListener(this);
helpMenu.getItem(6).addActionListener(this);
deployButton.addActionListener(this);
importButton.addActionListener(this);
@@ -147,7 +155,7 @@ public class MissPiggy implements ActionListener {
// display window
try {
windowIcon = ImageIO.read(new File(System.getProperty("user.dir") + "/resources/titleIcon.png"));
windowIcon = ImageIO.read(Main.class.getResourceAsStream("/titleIcon.png"));
frame.setIconImage(windowIcon);
} catch (IOException e) {
System.out.println("ERROR: Failed to find /resources/titleIcon.png. Window will not have an icon.");
@@ -169,6 +177,8 @@ public class MissPiggy implements ActionListener {
importButton.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
deployButton.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
((DefaultCaret)descriptionField.getCaret()).setUpdatePolicy(DefaultCaret.NEVER_UPDATE); // prevent automatically scrolling to the bottom when mod details exceed window size
frame.setSize(800, 600); // 1280 800
frame.setMinimumSize(new Dimension(640,480));
frame.setTitle("Firestar Mod Manager");
@@ -176,6 +186,9 @@ public class MissPiggy implements ActionListener {
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
if (Main.checkUpdates) { StartErnie(); }
frame.setVisible(true);
}
@@ -184,7 +197,6 @@ public class MissPiggy implements ActionListener {
Main.Mods.clear();
// get current list of mods from file
// todo: rewrite when modpacks/playlists are added
try {
priorityList = new String(Files.readAllBytes(Paths.get(System.getProperty("user.home") + "/.firestar/mods/index")));
} catch (IOException e) {
@@ -301,6 +313,15 @@ public class MissPiggy implements ActionListener {
modList.setListData(contents);
createSelectionEventListener();
}
private void StartErnie() {
new Thread(new Runnable() {
@Override
public void run() {
new Ernie(frame); // changed away from runnable in order to pass params to constructor -bonk
}
}).start();
}
private ListSelectionListener whenItemSelected() {
return null;
@@ -325,7 +346,7 @@ 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)) {throwUnimplemented();} else
if (actionEvent.getSource() == toolsMenu.getItem(2)) {new Suggs(frame);} else
if (actionEvent.getSource() == helpMenu.getItem(0)) {
try {
@@ -351,7 +372,8 @@ public class MissPiggy implements ActionListener {
JOptionPane.showMessageDialog(frame, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
} else
if (actionEvent.getSource() == helpMenu.getItem(5)) {new Rowlf().displayAboutScreen();}
if (actionEvent.getSource() == helpMenu.getItem(5)) {StartErnie();} else
if (actionEvent.getSource() == helpMenu.getItem(6)) {new Rowlf(frame);}
}
// Will likely split the below functions into separate classes to work with intellij GUI designer.
@@ -363,12 +385,28 @@ public class MissPiggy implements ActionListener {
}
if (i > 0) {
int result = JOptionPane.showConfirmDialog(frame, "A new PSARC will be generated. This can take several minutes.\nDuring this time, your computer may be very busy or slow.\n\nAre you sure you want to continue?", "Deploy Mods", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
int result = JOptionPane.showConfirmDialog(frame, "A new PSARC will be generated. This can take several minutes.\nDuring this time, your computer may be very busy or slow.\n\nIt will be placed in: " + Main.outpath + "\n\nAre you sure you want to continue?", "Deploy Mods", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
// prevent interruptions
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setEnabled(false);
if (!new File(Main.inpath + "psp2psarc.exe").exists()) {
JOptionPane.showMessageDialog(frame, "psp2psarc is missing.\nPlease select \"Get Dependencies\" in the Options menu.", "Error", JOptionPane.ERROR_MESSAGE);
wrapUpDeployment();
return;
}
if (!new File(Main.inpath + "data.psarc").exists() &&
!new File(Main.inpath + "data1.psarc").exists() &&
!new File(Main.inpath + "data2.psarc").exists() &&
!new File(Main.inpath + "dlc1.psarc").exists() &&
!new File(Main.inpath + "dlc2.psarc").exists()) {
JOptionPane.showMessageDialog(frame, "You have no PSARCs.\nPlease dump your copy of WipEout 2048 or download a PSARC from the Options menu.", "Error", JOptionPane.ERROR_MESSAGE);
wrapUpDeployment();
return;
}
// start
new Gonzo().DeployMods(this);
}

View File

@@ -5,16 +5,22 @@
<constraints>
<xy x="20" y="20" width="1464" height="573"/>
</constraints>
<properties/>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<component id="a5cc7" class="javax.swing.JLabel" binding="picLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false">
<maximum-size width="-1" height="100"/>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false">
<maximum-size width="333" height="100"/>
</grid>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Aww fiddlesticks, what now?"/>
</properties>
</component>
@@ -26,6 +32,11 @@
</grid>
</constraints>
<properties>
<background color="-2271221"/>
<editable value="false"/>
<focusable value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<horizontalAlignment value="0"/>
<text value="Do you think we should appeal to the alien authorities?"/>
</properties>
@@ -38,6 +49,8 @@
</grid>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Version Unknown"/>
</properties>
</component>
@@ -49,6 +62,8 @@
</grid>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Platform Unknown"/>
</properties>
</component>

View File

@@ -26,21 +26,28 @@ import java.io.IOException;
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
public class Rowlf {
private BufferedImage windowIcon;
JFrame frame = new JFrame();
JPanel frameContainer;
BufferedImage logo;
Image logo;
JLabel picLabel;
private JTextField informationText;
private JLabel versionLabel;
private JLabel environmentLabel;
public void displayAboutScreen() {
public Rowlf(JFrame parent) {
try {
logo = ImageIO.read(new File(System.getProperty("user.dir") + "/resources/logo_about.png"));
logo = ImageIO.read(Main.class.getResourceAsStream("/logo.png")).getScaledInstance(333, 100, Image.SCALE_SMOOTH);
} catch (IOException e) {
System.out.println("ERROR: Failed to open About screen because we couldn't find an image needed to display the page.");
throw new RuntimeException(e);
}
try {
windowIcon = ImageIO.read(Main.class.getResourceAsStream("/titleIcon.png"));
frame.setIconImage(windowIcon);
} catch (IOException e) {
System.out.println("ERROR: Failed to find /resources/titleIcon.png. Window will not have an icon.");
}
//frame.add(picLabel);
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
@@ -52,7 +59,7 @@ public class Rowlf {
"\n" +
"Special thanks to:\n" +
"ThatOneBonk, for Thallium and for modding help\n" +
"Wirlaburla, for web hosting and being awesome\n" +
"Wirlaburla, for web hosting and code assistance\n" +
"Psygnosis, for making our favorite game ever\n" +
"and to all the PSVita hackers who made this possible");
informationText.setHighlighter(null);
@@ -69,7 +76,7 @@ public class Rowlf {
frame.setAlwaysOnTop(true);
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setLocationRelativeTo(parent);
frame.setVisible(true);
}
}

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="Scooter">
<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="500" height="400"/>
</constraints>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<component id="4913b" class="javax.swing.JProgressBar" binding="progressBar">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="50" height="-1"/>
<maximum-size width="200" height="-1"/>
</grid>
</constraints>
<properties>
<background color="-1"/>
<borderPainted value="false"/>
<foreground color="-2271221"/>
<indeterminate value="false"/>
<stringPainted value="true"/>
<value value="0"/>
</properties>
</component>
<component id="46ede" class="javax.swing.JLabel" binding="label">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value=""/>
</properties>
</component>
</children>
</grid>
</form>

View File

@@ -0,0 +1,79 @@
/*
* Firestar Mod Manager
* Copyright (C) 2024 bonkmaykr
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
public class Scooter {
private JFrame frame = new JFrame();
public JProgressBar progressBar;
private JPanel frameContainer;
private JLabel label;
public void showDialog(String title) {
frame.add(frameContainer);
frame.setSize(300, 100);
frame.setTitle(title);
frame.setResizable(false);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setAlwaysOnTop(true);
frame.setIconImage(Main.windowIcon);
progressBar.setStringPainted(true);
frame.setVisible(true);
}
public void setProgressMin(int i) {
progressBar.setMinimum(i);
}
public void setProgressValue(int i) {
progressBar.setValue(i);
}
public void setProgressMax(int i) {
progressBar.setMaximum(i);
}
public int getProgressMin() {
return progressBar.getMinimum();
}
public int getProgressValue() {
return progressBar.getValue();
}
public int getProgressMax() {
return progressBar.getMaximum();
}
public void setText(String text) {
label.setText(text);
}
public void destroyDialog() {
frame.setVisible(false);
frame.dispose();
}
}

View File

@@ -0,0 +1,371 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="Suggs">
<grid id="27dc6" binding="frameContainer" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<constraints>
<xy x="20" y="20" width="756" height="460"/>
</constraints>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<scrollpane id="bd8d3">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<opaque value="false"/>
</properties>
<border type="line" title="Song List">
<font name="Exo 2"/>
<title-color color="-1"/>
<color color="-1"/>
</border>
<children>
<component id="1b9e1" class="javax.swing.JList" binding="dSongList">
<constraints/>
<properties>
<background color="-15128227"/>
<foreground color="-1"/>
<opaque value="true"/>
<selectionBackground color="-2271221"/>
<selectionForeground color="-1"/>
</properties>
</component>
</children>
</scrollpane>
<grid id="eb54e" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<foreground color="-1"/>
<opaque value="false"/>
</properties>
<border type="none"/>
<children>
<component id="adce7" class="javax.swing.JButton" binding="cancelBtn">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="2" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Cancel"/>
</properties>
</component>
<hspacer id="8ecbf">
<constraints>
<grid row="0" column="0" row-span="2" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<component id="b6c2f" class="javax.swing.JCheckBox" binding="checkAdditive">
<constraints>
<grid row="0" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<enabled value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<opaque value="false"/>
<text value="Append to default playlist"/>
<visible value="false"/>
</properties>
</component>
<component id="a7b02" class="javax.swing.JButton" binding="saveBtn">
<constraints>
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="2" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Save"/>
</properties>
</component>
</children>
</grid>
<grid id="cc2" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="3" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<component id="aa38f" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<foreground color="-1"/>
<text value="Title"/>
</properties>
</component>
<component id="9667" class="javax.swing.JTextField" binding="fTitle">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="f7802" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<foreground color="-1"/>
<text value="Artist"/>
</properties>
</component>
<component id="7fc56" class="javax.swing.JTextField" binding="fArtist">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<grid id="27515" 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="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<component id="fbefd" class="javax.swing.JLabel" binding="dTrackNo">
<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>
<background color="-15128227"/>
<foreground color="-1"/>
<text value="track # here (in MT_xx format)"/>
</properties>
</component>
<component id="a659e" class="javax.swing.JLabel" binding="dFileSize">
<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>
<background color="-15128227"/>
<foreground color="-1"/>
<text value="file size here"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
<grid id="568f5" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<opaque value="false"/>
</properties>
<border type="none"/>
<children>
<component id="cc5fd" class="javax.swing.JButton" binding="frontendDemoChooseBtn">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Select Multiplayer Menu Track"/>
</properties>
</component>
<component id="fb30a" class="javax.swing.JButton" binding="frontendMainChooseBtn">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Select Singleplayer Menu Track"/>
</properties>
</component>
<component id="e9b40" class="javax.swing.JButton" binding="deleteSongBtn">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Delete Song"/>
</properties>
</component>
<component id="f5254" class="javax.swing.JButton" binding="moveDownBtn">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Move Down"/>
</properties>
</component>
<component id="6b3fa" class="javax.swing.JButton" binding="addSongBtn">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Add Song"/>
</properties>
</component>
<component id="38ad" class="javax.swing.JButton" binding="moveUpBtn">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Move Up"/>
</properties>
</component>
</children>
</grid>
<grid id="2d649" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="2" left="2" bottom="2" right="2"/>
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="-1" height="100"/>
<maximum-size width="-1" height="300"/>
</grid>
</constraints>
<properties>
<opaque value="false"/>
</properties>
<border type="line" title="Info">
<font name="Exo 2"/>
<title-color color="-1"/>
<color color="-1"/>
</border>
<children>
<grid id="6168c" layout-manager="GridLayoutManager" row-count="7" 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="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="43fad" class="javax.swing.JLabel">
<constraints>
<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>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Menu:"/>
</properties>
</component>
<component id="74c7a" class="javax.swing.JLabel">
<constraints>
<grid row="4" 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>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Lobby:"/>
</properties>
</component>
<component id="1fda4" class="javax.swing.JLabel" binding="dSTitle">
<constraints>
<grid row="1" 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>
<font name="Exo 2" style="2"/>
<foreground color="-1"/>
<text value="no track"/>
</properties>
</component>
<component id="99b42" class="javax.swing.JLabel" binding="dMTitle">
<constraints>
<grid row="5" 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>
<font name="Exo 2" style="2"/>
<foreground color="-1"/>
<text value="no track"/>
</properties>
</component>
<component id="c11e8" class="javax.swing.JLabel" binding="dSSize">
<constraints>
<grid row="2" 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>
<font name="Exo 2" style="2"/>
<foreground color="-1"/>
<text value="no size"/>
</properties>
</component>
<component id="8480f" class="javax.swing.JLabel" binding="dMSize">
<constraints>
<grid row="6" 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>
<font name="Exo 2" style="2"/>
<foreground color="-1"/>
<text value="no size"/>
</properties>
</component>
<vspacer id="73ce0">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
</children>
</grid>
</children>
</grid>
</children>
</grid>
</form>

View File

@@ -0,0 +1,400 @@
/*
* Firestar Mod Manager
* Copyright (C) 2024 bonkmaykr
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
public class Suggs implements ActionListener, ListSelectionListener {
public JFrame frame = new JFrame();
private JPanel frameContainer;
private JList dSongList;
private JButton moveDownBtn;
private JButton saveBtn;
private JButton cancelBtn;
private JTextField fTitle;
private JTextField fArtist;
private JLabel dTrackNo;
private JLabel dFileSize;
private JButton frontendDemoChooseBtn;
private JButton frontendMainChooseBtn;
private JButton deleteSongBtn;
private JButton addSongBtn;
private JButton moveUpBtn;
private JLabel dSTitle;
private JLabel dMTitle;
private JLabel dSSize;
private JLabel dMSize;
private JCheckBox checkAdditive;
private Scooter progressDialog;
JFrame parent;
int curIndex = -1;
public class AudioTrack {
public File path; // file name
public String title; // audio title
public String artist; // audio artist
public long size; // file size in bytes
public boolean noConvert;
}
private static List<AudioTrack> tracklist = new ArrayList<AudioTrack>();
private File sptrack;
private File mptrack;
public Suggs(JFrame parent) {
this.parent = parent;
parent.setEnabled(false);
frame.setIconImage(Main.windowIcon);
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
frame.setSize(700, 400);
frame.setMinimumSize(new Dimension(650,280));
frame.setTitle("Soundtrack Mod Generator");
frame.setResizable(true);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(parent);
frame.setAlwaysOnTop(true);
cancelBtn.addActionListener(this); // TODO: put warning dialog "Are you sure? All unsaved changes will be lost."
saveBtn.addActionListener(this);
addSongBtn.addActionListener(this); // file picker
deleteSongBtn.addActionListener(this); // delete from list
moveUpBtn.addActionListener(this);
moveDownBtn.addActionListener(this);
fTitle.addActionListener(this); // automatically change selected item when changed &
fArtist.addActionListener(this); // also update field when new item selected
frontendMainChooseBtn.addActionListener(this); // file picker for singleplayer campaign grid music
frontendDemoChooseBtn.addActionListener(this); // file picker for multiplayer lobby music
dSongList.addListSelectionListener(this);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{// TODO: put warning dialog "Are you sure? All unsaved changes will be lost."
parent.setEnabled(true);
e.getWindow().dispose();
}
});
frame.setVisible(true);
}
private void haveSeggs() { // kill yourself
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == cancelBtn) {
parent.setEnabled(true);
frame.dispose();
} else
if (actionEvent.getSource() == fTitle || actionEvent.getSource() == fArtist) {
tracklist.get(curIndex).title = fTitle.getText();
tracklist.get(curIndex).artist = fArtist.getText();
InitializeSongListInGUI();
dSongList.setSelectedIndex(curIndex);
} else
if (actionEvent.getSource() == addSongBtn) {addSong();} else
if (actionEvent.getSource() == deleteSongBtn) {remove(curIndex);} else
if (actionEvent.getSource() == moveUpBtn) {moveUp(curIndex);} else
if (actionEvent.getSource() == moveDownBtn) {moveDown(curIndex);} else
if (actionEvent.getSource() == frontendMainChooseBtn) {setSPMusic();} else
if (actionEvent.getSource() == frontendDemoChooseBtn) {setMPMusic();} else
if (actionEvent.getSource() == saveBtn) {save();}
}
@Override
public void valueChanged(ListSelectionEvent listSelectionEvent) {
curIndex = dSongList.getSelectedIndex();
if (curIndex >= 0) {
AudioTrack at = tracklist.get(curIndex);
fTitle.setText(at.title);
fArtist.setText(at.artist);
dTrackNo.setText(String.format("MT_%02d", curIndex));
dFileSize.setText((at.size / 1000) + "kb");
} else {
fTitle.setText("");
fArtist.setText("");
dTrackNo.setText("--");
dFileSize.setText("-kb");
}
}
private void remove(int index) {
if (index >= 0) {
tracklist.remove(index);
InitializeSongListInGUI();
}
}
private void moveUp(int index) {
if (index > 0) {
Collections.swap(tracklist, index, index - 1);
InitializeSongListInGUI();
}
}
private void moveDown(int index) {
if (index < (tracklist.size() - 1)) {
Collections.swap(tracklist, index, index + 1);
InitializeSongListInGUI();
}
}
private void InitializeSongListInGUI() {
dSongList.clearSelection();
dSongList.removeAll();
dSongList.setVisibleRowCount(tracklist.size());
dSongList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// add text entry for each
int i = 0;
String[] contents = new String[tracklist.size()];
while (i < tracklist.size()) {
if (tracklist.get(i).title == null || tracklist.get(i).title.isEmpty())
{tracklist.get(i).title = tracklist.get(i).path.getName();}
if (tracklist.get(i).artist == null || tracklist.get(i).artist.isEmpty())
{tracklist.get(i).artist = "???";}
contents[i] = tracklist.get(i).artist + " - " + tracklist.get(i).title;
i++;
}
dSongList.setListData(contents);
dSongList.setSelectedIndex(curIndex);
}
private void setSPMusic() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("WAVE", "wav"));
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("ATRAC9", "at9"));
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
sptrack = selectedFile;
dSTitle.setText(selectedFile.getName());
dSSize.setText((selectedFile.length() / 1000) + "kb");
}
}
private void setMPMusic() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("WAVE", "wav"));
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("ATRAC9", "at9"));
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
mptrack = selectedFile;
dMTitle.setText(selectedFile.getName());
dMSize.setText((selectedFile.length() / 1000) + "kb");
}
}
private void addSong() {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setMultiSelectionEnabled(true);
fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("WAVE", "wav"));
fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("ATRAC9", "at9"));
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
File[] selectedFiles = fileChooser.getSelectedFiles();
for (File f : selectedFiles) {
if (f.exists()) {
System.out.println("Importing audio file \"" + f.getName() + "\"");
AudioTrack track = new AudioTrack();
track.path = f;
String fname = f.getName();
if (fname.contains(" - ")) {
track.title = fname.substring(fname.indexOf(" - ")+3, fname.lastIndexOf("."));
track.artist = fname.substring(0, fname.indexOf(" - "));
} else track.title = fname;
track.size = f.length();
tracklist.add(track);
}
}
InitializeSongListInGUI();
}
}
private void save() {
if (tracklist.isEmpty() && sptrack == null && mptrack == null) {
JOptionPane.showMessageDialog(frame, "Please add at least one song to the playlist.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
frame.setEnabled(false);
frame.setAlwaysOnTop(false);
Main.deleteDir(new File(System.getProperty("user.home") + "/.firestar/temp/")); // starts with clean temp
new Thread(() -> {
int progressSize = tracklist.size()+(sptrack != null?1:0)+(mptrack != null?1:0)+3; // Accounting for processes
progressDialog = new Scooter();
progressDialog.showDialog("Soundtrack Mod Generator");
progressDialog.setText("Generating audio files...");
progressDialog.setProgressMax(progressSize);
progressDialog.setProgressValue(0);
new File(Main.inpath + "temp/data/audio/music").mkdirs();
for (int i = 0; i < tracklist.size(); i++) {
AudioTrack at = tracklist.get(i);
String trackno = String.format("%02d", i);
new File(Main.inpath + "temp/data/audio/music/" + trackno).mkdirs();
if (at.path.getName().endsWith(".at9")) {
progressDialog.setText("Copying track " + (i+1) + " out of " + tracklist.size() + "...");
try {
// Assume whoever made the AT9s knows what they're doing
System.out.println("Copying track #" + (i+1) + " \"" + at.title + " - " + at.artist + "\"...");
Files.copy(at.path.toPath(), Paths.get(Main.inpath + "tmp/data/audio/music/" + trackno + "/music_stereo.at9"), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
progressDialog.setText("Encoding track " + (i+1) + " out of " + tracklist.size() + "...");
try {
System.out.println("Encoding track #" + (i+1) + " \"" + at.title + " - " + at.artist + "\"...");
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/");
p.waitFor();
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
}
progressDialog.setProgressValue(i+1);
}
if (sptrack != null) {
progressDialog.setText("Encoding singleplayer frontend track...");
if (sptrack.exists()) {
try {
System.out.println("Encoding singleplayer frontend track...");
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/");
p.waitFor();
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
}
progressDialog.setProgressValue(progressDialog.getProgressValue()+1);
}
if (mptrack != null) {
progressDialog.setText("Encoding multiplayer frontend track...");
try {
assert(mptrack.exists());
System.out.println("Encoding multiplayer frontend track...");
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/");
p.waitFor();
} catch (IOException | InterruptedException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
progressDialog.setProgressValue(progressDialog.getProgressValue()+1);
}
System.out.println("Finished encoding.");
progressDialog.setText("Generating Music Definitions...");
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document defDoc = docBuilder.newDocument();
Element docScreen = defDoc.createElement("Screen");
docScreen.setAttribute("name", "Top");
for (int i = 0; i < tracklist.size(); i++) { // TODO: support for additive
AudioTrack at = tracklist.get(i);
String trackno = String.format("%02d", i);
Element trackElem = defDoc.createElement("PI_Music");
trackElem.setAttribute("name", trackno);
Element pathElem = defDoc.createElement("Values");
pathElem.setAttribute("location", "data\\audio\\music\\"+trackno);
trackElem.appendChild(pathElem);
Element artistElem = defDoc.createElement("Entry");
artistElem.setAttribute("Artist", at.artist);
trackElem.appendChild(artistElem);
Element titleElem = defDoc.createElement("Entry");
titleElem.setAttribute("Label", at.title);
trackElem.appendChild(titleElem);
docScreen.appendChild(trackElem);
System.out.println("Adding \"" + trackno + ". " + at.artist + " - " + at.title + "\" to Definition.xml");
}
defDoc.appendChild(docScreen);
new File(Main.inpath + "temp/data/plugins/music/").mkdirs();
FileOutputStream output = new FileOutputStream(Main.inpath + "temp/data/plugins/music/Definition.xml");
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(defDoc);
StreamResult result = new StreamResult(output);
transformer.transform(source, result);
} catch (IOException | ParserConfigurationException | TransformerException ex) {
Logger.getLogger(Suggs.class.getName()).log(Level.SEVERE, null, ex);
}
progressDialog.setProgressValue(progressDialog.getProgressValue()+1);
progressDialog.setText("Localizing...");
System.out.println("Creating localization edits for music tracks...");
// TODO: Actually do what the above print-out says
progressDialog.setProgressValue(progressDialog.getProgressValue()+1);
progressDialog.destroyDialog();
frame.dispose();
new Clifford().Action(frame, new File(Main.inpath + "temp/"));
parent.setEnabled(true);
}).start();
}
}

View File

@@ -0,0 +1,250 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="Waldorf">
<grid id="27dc6" binding="frameContainer" layout-manager="GridLayoutManager" row-count="7" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="25" bottom="10" right="25"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties>
<background color="-15128227"/>
<foreground color="-1"/>
<maximumSize width="50" height="100"/>
<minimumSize width="50" height="100"/>
<preferredSize width="50" height="100"/>
</properties>
<border type="none"/>
<children>
<component id="db731" class="javax.swing.JLabel">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Mod Export Path"/>
</properties>
</component>
<component id="e2cd7" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="3" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value=".firestar Folder"/>
</properties>
</component>
<component id="63b35" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Downloads"/>
</properties>
</component>
<grid id="1206c" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="3" left="5" bottom="3" right="5"/>
<constraints>
<grid row="0" column="1" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<foreground color="-1"/>
</properties>
<border type="line">
<font name="Exo 2"/>
<title-color color="-1"/>
<color color="-1"/>
</border>
<children>
<component id="92a60" class="javax.swing.JButton" binding="dwnSDKbtn">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Get Dependencies"/>
</properties>
</component>
<component id="87ead" class="javax.swing.JButton" binding="dwnARCbtn">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Auto-Download PSARCs"/>
</properties>
</component>
</children>
</grid>
<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"/>
</constraints>
<properties>
<opaque value="false"/>
</properties>
<border type="none"/>
<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"/>
</constraints>
<properties>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Deploys Go Here"/>
</properties>
</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"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Change"/>
</properties>
</component>
</children>
</grid>
<component id="73ca5" class="javax.swing.JCheckBox" binding="checkUpdatesToggle">
<constraints>
<grid row="5" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<label value="Automatically check for updates on startup"/>
<opaque value="false"/>
<rolloverEnabled value="false"/>
<text value="Automatically check for updates on startup"/>
</properties>
</component>
<grid id="6078c" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="3" left="5" bottom="3" right="5"/>
<constraints>
<grid row="1" column="1" row-span="3" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<foreground color="-1"/>
<opaque value="false"/>
</properties>
<border type="line">
<font name="Exo 2"/>
<title-color color="-1"/>
<color color="-1"/>
</border>
<children>
<component id="8fec2" class="javax.swing.JButton" binding="bOpenFolder">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<label value="Browse"/>
<text value="Browse"/>
</properties>
</component>
<component id="b08c4" class="javax.swing.JButton" binding="bDelArcs">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<label value="Delete PSARCs"/>
<text value="Delete PSARCs"/>
</properties>
</component>
</children>
</grid>
<grid id="d0121" layout-manager="GridLayoutManager" row-count="1" 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="6" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<opaque value="false"/>
</properties>
<border type="none"/>
<children>
<component id="50d13" class="javax.swing.JButton" binding="cancelbtn">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="1" anchor="0" fill="0" indent="0" use-parent-layout="false">
<minimum-size width="100" height="-1"/>
<preferred-size width="200" height="-1"/>
<maximum-size width="200" height="-1"/>
</grid>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Cancel"/>
</properties>
</component>
<component id="252b3" class="javax.swing.JButton" binding="resetbtn">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="1" anchor="0" fill="0" indent="0" use-parent-layout="false">
<minimum-size width="100" height="-1"/>
<preferred-size width="200" height="-1"/>
<maximum-size width="200" height="-1"/>
</grid>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Restore Defaults"/>
</properties>
</component>
<component id="3d88f" class="javax.swing.JButton" binding="okbtn">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="1" anchor="0" fill="0" indent="0" use-parent-layout="false">
<minimum-size width="100" height="-1"/>
<preferred-size width="200" height="-1"/>
<maximum-size width="200" height="-1"/>
</grid>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<text value="Save"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
</form>

View File

@@ -16,8 +16,6 @@
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import org.json.JSONObject;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
@@ -36,36 +34,48 @@ public class Waldorf implements ActionListener {
private JPanel frameContainer;
private JButton okbtn;
private JButton cancelbtn;
private JTextField fOutpath;
private JLabel fOutpath;
private JButton resetbtn;
private JButton bOpenFolder;
private JButton dwnSDKbtn;
private JButton dwnARCbtn;
private JButton fOutpathChangebtn;
private JCheckBox checkUpdatesToggle;
private JButton bDelArcs;
MissPiggy invoker;
private String tOutPath = Main.outpath;
public void Action(MissPiggy inv) {
invoker = inv;
frame.add(frameContainer);
try {
BufferedImage windowIcon = ImageIO.read(new File(System.getProperty("user.dir") + "/resources/titleIcon.png"));
BufferedImage windowIcon = ImageIO.read(Main.class.getResourceAsStream("/titleIcon.png"));
frame.setIconImage(windowIcon);
} catch (IOException e) {
System.out.println("ERROR: Failed to find /resources/titleIcon.png. Window will not have an icon.");
}
frame.setSize(600, 200); // 1280 800
frame.setSize(600, 300); // 1280 800
frame.setMinimumSize(new Dimension(200,100));
frame.setTitle("Options");
frame.setResizable(false);
frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setLocationRelativeTo(inv.frame);
frame.setAlwaysOnTop(true);
cancelbtn.addActionListener(this);
okbtn.addActionListener(this);
resetbtn.addActionListener(this);
bOpenFolder.addActionListener(this);
bDelArcs.addActionListener(this);
dwnARCbtn.addActionListener(this);
dwnSDKbtn.addActionListener(this);
fOutpathChangebtn.addActionListener(this);
fOutpath.setText(Main.outpath);
checkUpdatesToggle.setSelected(Main.checkUpdates);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@@ -85,8 +95,10 @@ public class Waldorf implements ActionListener {
frame.dispose();
} else
if (actionEvent.getSource() == okbtn) {
Main.outpath = fOutpath.getText();
Main.outpath = tOutPath;
Main.checkUpdates = checkUpdatesToggle.isSelected();
Main.writeConf();
Main.loadConf();
invoker.frame.setEnabled(true);
frame.dispose();
@@ -94,7 +106,14 @@ public class Waldorf implements ActionListener {
if (actionEvent.getSource() == resetbtn) {
int result = JOptionPane.showConfirmDialog(frame,"Are you sure you want to redo the initial setup?", "Restore Default Settings", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
System.out.println("Restoring default settings");
new File(System.getProperty("user.home") + "/.firestar/firestar.conf").delete();
System.out.println("Deleting existing PSARCs");
new File(Main.inpath + "data.psarc").delete();
new File(Main.inpath + "data1.psarc").delete();
new File(Main.inpath + "data2.psarc").delete();
new File(Main.inpath + "dlc1.psarc").delete();
new File(Main.inpath + "dlc2.psarc").delete();
int result2 = JOptionPane.showConfirmDialog(frame,"Firestar will now close.", "Restore Default Settings", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE);
if (result2 == JOptionPane.OK_OPTION) {
System.exit(0);
@@ -107,6 +126,43 @@ public class Waldorf implements ActionListener {
} catch (IOException e) {
throw new RuntimeException(e);
}
}
} else
if (actionEvent.getSource() == bDelArcs) {
int result = JOptionPane.showConfirmDialog(frame, "All existing PSARC dumps will be deleted.\nDo you want to continue?", "Delete PSARCs", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (result == JOptionPane.NO_OPTION) {return;}
System.out.println("User requested arc wipe, deleting existing PSARCs");
new File(Main.inpath + "data.psarc").delete();
new File(Main.inpath + "data1.psarc").delete();
new File(Main.inpath + "data2.psarc").delete();
new File(Main.inpath + "dlc1.psarc").delete();
new File(Main.inpath + "dlc2.psarc").delete();
JOptionPane.showMessageDialog(frame, "PSARC files purged.", "Delete PSARCs", JOptionPane.INFORMATION_MESSAGE);
} else
if (actionEvent.getSource() == dwnARCbtn) {
new Bert(invoker.frame);
frame.dispose();
} else
if (actionEvent.getSource() == dwnSDKbtn) {
Thread downloaderPopupThread = new Thread(new Runnable() {
@Override
public void run() {
Main.downloadDependenciesBeforeSetVisible(invoker.frame);
invoker.frame.setEnabled(true);
}
});
downloaderPopupThread.start();
frame.dispose();
} else
if (actionEvent.getSource() == fOutpathChangebtn) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
if (fileChooser.getSelectedFile().isDirectory()) {
tOutPath = fileChooser.getSelectedFile().getAbsolutePath();
fOutpath.setText(tOutPath);
}
}
}
}
}

View File

@@ -0,0 +1,206 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="WilkinsCoffee">
<grid id="27dc6" binding="frameContainer" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<constraints>
<xy x="20" y="20" width="416" height="479"/>
</constraints>
<properties>
<background color="-15128227"/>
<foreground color="-1"/>
</properties>
<border type="none"/>
<children>
<component id="a7e40" class="javax.swing.JLabel" binding="picLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="1" anchor="1" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="76" height="76"/>
<maximum-size width="96" height="96"/>
</grid>
</constraints>
<properties>
<foreground color="-1"/>
<text value="Image"/>
</properties>
</component>
<component id="29913" class="javax.swing.JEditorPane" binding="instructions">
<constraints>
<grid row="0" column="1" row-span="2" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="1" use-parent-layout="false">
<preferred-size width="150" height="50"/>
</grid>
</constraints>
<properties>
<background color="-15128227"/>
<contentType value="text/html"/>
<disabledTextColor color="-592129"/>
<editable value="false"/>
<enabled value="false"/>
<focusCycleRoot value="false"/>
<focusable value="false"/>
<font name="Exo 2" size="14"/>
<foreground color="-1"/>
<margin top="0" left="5" bottom="0" right="0"/>
<text value="&lt;html&gt;&#10; &lt;head&gt;&#10; &#10; &lt;/head&gt;&#10; &lt;body&gt;&#10; &lt;p id=&quot;first-p&quot;&gt;&#10; Welcome to the Firestar Setup.&#10; &lt;/p&gt;&#10; &lt;p&gt;&#10; Please read the manual before continuing, and make sure your Vita is &#10; configured correctly first. You will need enso custom firmware and &#10; Repatch Reloaded for Firestar to work.&lt;br&gt;&lt;br&gt;Emulator players can skip &#10; these preparations.&#10; &lt;/p&gt;&#10; &lt;p&gt;&#10; Press &amp;quot;Continue&amp;quot; when you are ready.&#10; &lt;/p&gt;&#10; &lt;/body&gt;&#10;&lt;/html&gt;&#10;"/>
</properties>
</component>
<component id="c3ec3" class="javax.swing.JButton" binding="contBtn">
<constraints>
<grid row="4" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<foreground color="-1"/>
<text value="Continue"/>
</properties>
</component>
<grid id="ee2dd" binding="inputContainer" 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="3" right="0"/>
<constraints>
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<focusable value="false"/>
</properties>
<border type="none"/>
<children>
<component id="30c84" class="javax.swing.JButton" binding="PSARC_impBtn">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="2" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<foreground color="-1"/>
<text value="Import My Own"/>
</properties>
</component>
<component id="1c41b" class="javax.swing.JButton" binding="PSARC_downBtn">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="2" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<foreground color="-1"/>
<text value="Auto-Download"/>
</properties>
</component>
</children>
</grid>
<grid id="8468" binding="inputContainer2" 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="3" right="0"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
</properties>
<border type="none"/>
<children>
<component id="2cef5" class="javax.swing.JButton" binding="EXPORT_openFolderBtn">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-2271221"/>
<borderPainted value="false"/>
<focusPainted value="false"/>
<foreground color="-1"/>
<text value="Select Folder"/>
</properties>
</component>
<component id="31a4b" class="javax.swing.JLabel" binding="pathDisplay">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<font name="Exo 2" size="12"/>
<foreground color="-1"/>
<text value="Your Documents folder is selected by default."/>
</properties>
</component>
</children>
</grid>
<grid id="71c64" binding="checklistContainer" layout-manager="GridLayoutManager" row-count="5" 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="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="2" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<background color="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<opaque value="false"/>
</properties>
<border type="none"/>
<children>
<component id="eae72" class="javax.swing.JLabel" binding="checklistFury">
<constraints>
<grid row="4" 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="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<icon value="lightNegative.png"/>
<text value="Fury DLC"/>
</properties>
</component>
<component id="ae838" class="javax.swing.JLabel" binding="checklistHD">
<constraints>
<grid row="3" 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="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<icon value="lightNegative.png"/>
<text value="HD DLC"/>
</properties>
</component>
<component id="35a85" class="javax.swing.JLabel" binding="checklistPatch2">
<constraints>
<grid row="2" 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="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<icon value="lightNegative.png"/>
<text value="Patch 2"/>
</properties>
</component>
<component id="4ca0c" class="javax.swing.JLabel" binding="checklistPatch1">
<constraints>
<grid row="1" 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="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<icon value="lightNegative.png"/>
<text value="Patch 1"/>
</properties>
</component>
<component id="94f98" class="javax.swing.JLabel" binding="checklistBase">
<constraints>
<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="-15128227"/>
<font name="Exo 2"/>
<foreground color="-1"/>
<icon value="lightNegative.png"/>
<text value="Base"/>
</properties>
</component>
</children>
</grid>
</children>
</grid>
</form>

View File

@@ -0,0 +1,325 @@
/*
* Firestar Mod Manager
* Copyright (C) 2024 bonkmaykr
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.html.HTMLDocument;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import static javax.swing.WindowConstants.EXIT_ON_CLOSE;
public class WilkinsCoffee implements ActionListener {
BufferedImage windowIcon;
Image logo;
public Pages page;
public JFrame frame = new JFrame();
private JPanel frameContainer;
private JLabel picLabel;
private JEditorPane instructions;
private JButton contBtn;
private JPanel inputContainer;
private JButton PSARC_downBtn;
private JButton PSARC_impBtn;
private JPanel inputContainer2;
private JButton EXPORT_openFolderBtn;
private JLabel pathDisplay;
private JPanel checklistContainer;
private JLabel checklistFury;
private JLabel checklistHD;
private JLabel checklistPatch2;
private JLabel checklistPatch1;
private JLabel checklistBase;
public enum Pages {
INTRO(0),
PSARC(1),
EXPORT_LOCATION(2),
DONE(3);
public final int value;
private Pages(int i) {
this.value = i;
}
}
private String outPathTemp = System.getProperty("user.home") + "/Documents";
private boolean sdkInstalled = false;
public void setup() {
page = Pages.INTRO;
inputContainer.setVisible(false);
checklistContainer.setVisible(false);
inputContainer2.setVisible(false);
// check if this is windows or not
if(System.getProperty("os.name").contains("Windows")) {Main.windows = true;System.out.println("Assuming we should NOT use WINE based on known system variables.");}
else {Main.windows = false;System.out.println("Assuming we should use WINE based on known system variables.");}
// reformat path slightly for windows
if (Main.windows) {outPathTemp.replace("/", "\\");}
try {
windowIcon = ImageIO.read(Main.class.getResourceAsStream("/titleIcon.png"));
frame.setIconImage(windowIcon);
} catch (IOException e) {
System.out.println("ERROR: Failed to find /resources/titleIcon.png. Window will not have an icon.");
}
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/programIcon.png")).getScaledInstance(96, 96, Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
} catch (IOException e) {
System.out.println("ERROR: Missing resource in Wilkins. Page will be without images.");
picLabel.setText("");
}
String bodyRule = "html, body {margin:0px;} p#first-p {margin-top:-13px;} p {margin-left:-20px;}";
((HTMLDocument)instructions.getDocument()).getStyleSheet().addRule(bodyRule);
instructions.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE); // makes text smaller than joe biden's windmill if font set manually. wtf??
contBtn.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
PSARC_downBtn.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
PSARC_impBtn.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
EXPORT_openFolderBtn.setFont(Main.fExo2.deriveFont(Font.BOLD).deriveFont(12f));
frame.add(frameContainer); // initialize window contents -- will be handled by IntelliJ IDEA
contBtn.addActionListener(this);
PSARC_downBtn.addActionListener(this);
PSARC_impBtn.addActionListener(this);
EXPORT_openFolderBtn.addActionListener(this);
frame.setSize(400, 400);
frame.setTitle("Firestar Setup");
frame.setResizable(false);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLayout(new GridLayout());
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
WilkinsCoffee threadParent = this;
if (actionEvent.getSource() == PSARC_downBtn) {
Thread waiterThread = new Thread(new Runnable() {@Override
public void run() {
if (new Bert(frame).reportWhenDownloaded(threadParent)) {
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
refreshChecklist();
}
}});
waiterThread.start();
} else
if (actionEvent.getSource() == PSARC_impBtn) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
FileFilter fileChooserFilter = new FileNameExtensionFilter("Sony Playstation Archive File", "psarc");
fileChooser.setFileFilter(fileChooserFilter);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
try {
Files.copy(fileChooser.getSelectedFile().toPath(), new File(Main.inpath + fileChooser.getSelectedFile().getName()).toPath());
refreshChecklist();
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} catch (IOException e) {
System.out.println(e.getMessage());
JOptionPane.showMessageDialog(frame, "An error has occured.\n" + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
} else
if (actionEvent.getSource() == EXPORT_openFolderBtn) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
if (fileChooser.getSelectedFile().isDirectory()) {
outPathTemp = fileChooser.getSelectedFile().getAbsolutePath();
pathDisplay.setText("Export path: " + outPathTemp);
}
}
} else
if (actionEvent.getSource() == contBtn) {
switch (page) {
case INTRO:
if (!new File(Main.inpath + "psp2psarc.exe").exists()) { // we may have been here before // nag
frame.setEnabled(false);
int result = JOptionPane.showConfirmDialog(frame, "Firestar needs to download additional software to function. Setup is automatic and will only take a few minutes.\nIf you select NO, you will have to download additional dependencies later on.\n\nContinue?", "Firestar Setup", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION) {
sdkInstalled = true;
Thread downloaderPopupThread = new Thread(new Runnable() {
@Override
public void run() {
Main.downloadDependenciesBeforeSetVisible(frame);
frame.setEnabled(true);
}
});
downloaderPopupThread.start();
} else {
frame.setEnabled(true);
}
} else {
sdkInstalled = true;
}
page = Pages.PSARC;
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/setupIconPSARC.png")).getScaledInstance(96, 96, Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
} catch (IOException e) {
System.out.println("ERROR: Missing resource in Wilkins. Page will be without images.");
picLabel.setText("");
}
contBtn.setEnabled(false);
contBtn.setBackground(new Color(102, 74, 58)); //brown
refreshChecklist();
inputContainer.setVisible(true);
checklistContainer.setVisible(true);
if (!sdkInstalled) {
PSARC_downBtn.setEnabled(false);
PSARC_downBtn.setBackground(new Color(102, 74, 58)); //brown
}
instructions.setText("<html>\n" +
" <head>\n" +
" \n" +
" </head>\n" +
" <body>\n" +
" <p id=\"first-p\">\n" +
" You must dump the original assets from WipEout 2048 so that Firestar can patch them.<br><br>If you would like, you can choose to have these downloaded and extracted for you, or you can provide your own decrypted dumps.</p><p>To decrypt your own dumps, please see \"Decrypting Original PSARC Files\" in the manual.\n" +
" </p>\n" +
" <p>\n" +
" Press &quot;Continue&quot; when you are done.\n" +
" </p>\n" +
" </body>\n" +
"</html>\n");
break;
case PSARC:
page = Pages.EXPORT_LOCATION;
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/setupIconEXPORT.png")).getScaledInstance(96, 96, Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
} catch (IOException e) {
System.out.println("ERROR: Missing resource in Wilkins. Page will be without images.");
picLabel.setText("");
}
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
inputContainer.setVisible(false);
checklistContainer.setVisible(false);
inputContainer2.setVisible(true);
instructions.setText("<html>\n" +
" <head>\n" +
" \n" +
" </head>\n" +
" <body>\n" +
" <p id=\"first-p\">\n" +
" Almost done!<br><br>Select the folder you would like to export your compiled mods to.<br><br>When you select \"Deploy\" in the mod list, Firestar will place a PSARC file into this folder which you can install onto your Vita.\n" +
" </p>\n" +
" <p>\n" +
" Press &quot;Continue&quot; when you are done.\n" +
" </p>\n" +
" </body>\n" +
"</html>\n");
pathDisplay.setText("Export path: " + outPathTemp);
break;
case EXPORT_LOCATION:
page = Pages.DONE;
try {
logo = ImageIO.read(Main.class.getResourceAsStream("/setupIconDONE.png")).getScaledInstance(96, 96, Image.SCALE_SMOOTH);
picLabel.setIcon(new ImageIcon(logo));picLabel.setText("");
} catch (IOException e) {
System.out.println("ERROR: Missing resource in Wilkins. Page will be without images.");
picLabel.setText("");
}
inputContainer2.setVisible(false);
Main.outpath = outPathTemp + "/";
Main.repatch = true;
Main.writeConf();
instructions.setText("<html>\n" +
" <head>\n" +
" \n" +
" </head>\n" +
" <body>\n" +
" <p id=\"first-p\">\n" +
" Setup complete!\n" +
" </p>\n" +
" </body>\n" +
"</html>\n");
break;
case DONE:
frame.dispose();
new MissPiggy().Action();
break;
default:
throw new UnsupportedOperationException("ERROR: Setup page-flip event listener didn't drink any Wilkins Coffee. Get a programmer!");
}
}
}
private void refreshChecklist() {
ImageIcon positive = new ImageIcon(Main.class.getResource("/lightPositive.png"));
ImageIcon negative = new ImageIcon(Main.class.getResource("/lightNegative.png"));
// enabling the continue button here leaves the previous one redundant,
// but it's needed to ensure we don't force a redownload if the setup is interrupted
if(new File(Main.inpath + "data.psarc").exists()) {
checklistBase.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistBase.setIcon(negative);}
if(new File(Main.inpath + "data1.psarc").exists()) {
checklistPatch1.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistPatch1.setIcon(negative);}
if(new File(Main.inpath + "data2.psarc").exists()) {
checklistPatch2.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistPatch2.setIcon(negative);}
if(new File(Main.inpath + "dlc1.psarc").exists()) {
checklistHD.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistHD.setIcon(negative);}
if(new File(Main.inpath + "dlc2.psarc").exists()) {
checklistFury.setIcon(positive);
contBtn.setEnabled(true);
contBtn.setBackground(new Color(221, 88, 11)); //orange
} else {checklistFury.setIcon(negative);}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 B

View File

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 KiB

View File

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

1
gradle.properties Normal file
View File

@@ -0,0 +1 @@
netbeans.hint.jdkPlatform=JDK_22__System_

249
gradlew vendored Executable file
View File

@@ -0,0 +1,249 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

92
gradlew.bat vendored Normal file
View File

@@ -0,0 +1,92 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

14
settings.gradle Normal file
View File

@@ -0,0 +1,14 @@
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
* For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.8/userguide/multi_project_builds.html in the Gradle documentation.
*/
plugins {
// Apply the foojay-resolver plugin to allow automatic download of JDKs
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0'
}
rootProject.name = 'firestar'
include('firestar')

View File

@@ -1,74 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="Waldorf">
<grid id="27dc6" binding="frameContainer" layout-manager="GridLayoutManager" row-count="5" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties>
<maximumSize width="50" height="100"/>
<minimumSize width="50" height="100"/>
<preferredSize width="50" height="100"/>
</properties>
<border type="none"/>
<children>
<component id="3d88f" class="javax.swing.JButton" binding="okbtn">
<constraints>
<grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Save"/>
</properties>
</component>
<component id="86775" class="javax.swing.JTextField" binding="fOutpath">
<constraints>
<grid row="3" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="db731" class="javax.swing.JLabel">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Mod Export Path"/>
</properties>
</component>
<component id="50d13" class="javax.swing.JButton" binding="cancelbtn">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Cancel"/>
</properties>
</component>
<component id="252b3" class="javax.swing.JButton" binding="resetbtn">
<constraints>
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Restore Defaults"/>
</properties>
</component>
<component id="e2cd7" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="3" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value=".firestar Folder"/>
</properties>
</component>
<component id="c68f2" class="javax.swing.JButton" binding="bOpenFolder">
<constraints>
<grid row="0" column="1" row-span="3" col-span="2" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<label value="Browse"/>
<text value="Browse"/>
</properties>
</component>
</children>
</grid>
</form>