Compare commits
No commits in common. "master" and "v6.1" have entirely different histories.
63
.drone.yml
|
@ -4,7 +4,7 @@ name: default
|
|||
|
||||
steps:
|
||||
- name: test
|
||||
image: maven:3-openjdk-17
|
||||
image: maven:3-jdk-11
|
||||
commands:
|
||||
- mvn -B -DskipTests clean package
|
||||
- mvn test -B
|
||||
|
@ -16,69 +16,16 @@ steps:
|
|||
image: alpine:latest
|
||||
commands:
|
||||
- mkdir -p /builds/ns-usbloader
|
||||
- echo target/ns-usbloader-*jar
|
||||
- cp target/ns-usbloader-*jar /builds/ns-usbloader/
|
||||
volumes:
|
||||
- name: builds
|
||||
path: /builds
|
||||
|
||||
- name: make-win-installer
|
||||
image: wheatstalk/makensis:3
|
||||
commands:
|
||||
- cp target/NS-USBloader.exe misc/windows/NSIS/
|
||||
- misc/windows/update_version.sh
|
||||
- cd misc/windows/NSIS
|
||||
- makensis -V4 ./installer.nsi
|
||||
- echo Installer-*.exe
|
||||
- cp Installer-*.exe /builds/ns-usbloader/
|
||||
- rm ./NS-USBloader.exe
|
||||
- rm ./Installer-*.exe
|
||||
- cd ../../../
|
||||
volumes:
|
||||
- name: builds
|
||||
path: /builds
|
||||
- name: jdk
|
||||
path: /drone/src/misc/windows/NSIS/jdk
|
||||
- name: drivers
|
||||
path: /drone/src/misc/windows/NSIS/Drivers_set.exe
|
||||
|
||||
- name: emerge-legacy-artifact
|
||||
image: maven:3-openjdk-17
|
||||
image: maven:3-jdk-11
|
||||
commands:
|
||||
- . ./.make_legacy
|
||||
- mvn -B -DskipTests clean package
|
||||
- echo target/ns-usbloader-*jar
|
||||
- cp target/ns-usbloader-*jar /builds/ns-usbloader/
|
||||
volumes:
|
||||
- name: m2
|
||||
path: /root/.m2
|
||||
- name: builds
|
||||
path: /builds
|
||||
|
||||
- name: make-legacy-win-installer
|
||||
image: wheatstalk/makensis:3
|
||||
commands:
|
||||
- cp target/NS-USBloader.exe misc/windows/NSIS/
|
||||
- misc/windows/update_version.sh legacy
|
||||
- cd misc/windows/NSIS
|
||||
- makensis -V4 ./installer.nsi
|
||||
- echo Installer-*.exe
|
||||
- cp Installer-*.exe /builds/ns-usbloader/
|
||||
- cd ../../../
|
||||
volumes:
|
||||
- name: builds
|
||||
path: /builds
|
||||
- name: jdk
|
||||
path: /drone/src/misc/windows/NSIS/jdk
|
||||
- name: drivers
|
||||
path: /drone/src/misc/windows/NSIS/Drivers_set.exe
|
||||
|
||||
- name: emerge-mac-m1-artifact
|
||||
image: maven:3-openjdk-17
|
||||
commands:
|
||||
- . ./.make_m1
|
||||
- mvn -B -DskipTests clean package
|
||||
- echo target/ns-usbloader-*jar
|
||||
- cp target/ns-usbloader-*jar /builds/ns-usbloader/
|
||||
volumes:
|
||||
- name: m2
|
||||
|
@ -93,9 +40,3 @@ volumes:
|
|||
- name: builds
|
||||
host:
|
||||
path: /home/www/builds
|
||||
- name: jdk
|
||||
host:
|
||||
path: /home/docker/drone/files/assembly/openjdk-19.0.2
|
||||
- name: drivers
|
||||
host:
|
||||
path: /home/docker/drone/files/assembly/Drivers_set.exe
|
2
.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
offsets.txt
|
||||
environment.txt
|
|
@ -1,3 +1,2 @@
|
|||
sed -z -i -e 's/<groupId>org.usb4java<\/groupId>\n\s*<artifactId>usb4java<\/artifactId>\s*<version>1.3.0<\/version>/<groupId>org.usb4java<\/groupId>\n<artifactId>usb4java<\/artifactId>\n<version>1.2.0<\/version>/g' pom.xml
|
||||
sed -z -i -e 's/<finalName>${project.artifactId}-${project.version}-${maven.build.timestamp}<\/finalName>/<finalName>${project.artifactId}-${project.version}-legacy-${maven.build.timestamp}<\/finalName>/g' pom.xml
|
||||
sed -z -i -e 's/<jar>target\/${project.artifactId}-${project.version}-${maven.build.timestamp}.jar<\/jar>/<jar>target\/${project.artifactId}-${project.version}-legacy-${maven.build.timestamp}.jar<\/jar>/g' pom.xml
|
||||
|
|
5
.make_m1
|
@ -1,5 +0,0 @@
|
|||
sed -z -i -e 's/<groupId>org.usb4java<\/groupId>\n<artifactId>usb4java<\/artifactId>\n<version>1.2.0<\/version>/<groupId>org.usb4java<\/groupId>\n<artifactId>usb4java<\/artifactId>\n<version>1.3.0<\/version>/g' pom.xml
|
||||
sed -z -i -e 's/<classifier>mac<\/classifier>/<classifier>mac-aarch64<\/classifier>/g' pom.xml
|
||||
sed -z -i -e 's/<finalName>${project.artifactId}-${project.version}-legacy-${maven.build.timestamp}<\/finalName>/<finalName>${project.artifactId}-${project.version}-m1-${maven.build.timestamp}<\/finalName>/g' pom.xml
|
||||
sed -i -e '/<groupId>com.akathist.maven.plugins.launch4j/,/<\/executions>/d' pom.xml
|
||||
sed -z -i -e 's/<plugin>\n\s*<\/plugin>//g' pom.xml
|
87
README.md
|
@ -1,9 +1,9 @@
|
|||
<h1 align="center"><img src="screenshots/ApplicationLogo.svg" alt="NS-USBloader" width="450px"/></h1>
|
||||
# NS-USBloader
|
||||
|
||||
![License](https://img.shields.io/badge/License-GPLv3-blue.svg) ![Releases](https://img.shields.io/github/downloads/developersu/ns-usbloader/total.svg) ![LatestVer](https://img.shields.io/github/release/developersu/ns-usbloader.svg) [![Build Status](https://ci.redrise.ru/api/badges/desu/ns-usbloader/status.svg)](https://ci.redrise.ru/desu/ns-usbloader)
|
||||
|
||||
NS-USBloader is:
|
||||
* A PC-side installer for **[Huntereb/Awoo-Installer](https://github.com/Huntereb/Awoo-Installer)** / other compatible installers (USB and Network supported) and **[XorTroll/Goldleaf](https://github.com/XorTroll/Goldleaf)** (USB) NSP installer.
|
||||
* A PC-side installer for **[Huntereb/Awoo-Installer](https://github.com/Huntereb/Awoo-Installer)** / other compatible installers (USB and Network supported) and **[XorTroll/GoldLeaf](https://github.com/XorTroll/Goldleaf)** (USB) NSP installer.
|
||||
Alternative to default **usb_install_pc.py**, **remote_install_pc.py**, **GoldTree**/**Quark**.
|
||||
* RCM payload tool that works on Windows, macOS (Intel and Apple Silicon) and Linux (x86, amd64 and Raspberry Pi ARM).
|
||||
* It's a tool for creating split files!
|
||||
|
@ -22,9 +22,9 @@ With GUI and cookies. Works on Windows, macOS and Linux.
|
|||
|
||||
Sometimes I add new posts about this project [on my blog page](https://developersu.blogspot.com/search/label/NS-USBloader).
|
||||
|
||||
<img src="screenshots/1.png" alt="screenshot" width="250"/> <img src="screenshots/2.png" alt="screenshot" width="250"/>
|
||||
<img src="screenshots/3.png" alt="screenshot" width="250"/> <img src="screenshots/4.png" alt="screenshot" width="250"/>
|
||||
<img src="screenshots/5.png" alt="screenshot" width="250"/>
|
||||
![Application screenshot](screenshots/1.png)
|
||||
<img src="screenshots/2.png" alt="screenshot" width="250"/> <img src="screenshots/3.png" alt="screenshot" width="250"/>
|
||||
<img src="screenshots/4.png" alt="screenshot" width="250"/> <img src="screenshots/5.png" alt="screenshot" width="250"/>
|
||||
|
||||
#### License
|
||||
|
||||
|
@ -42,41 +42,36 @@ Sometimes I add new posts about this project [on my blog page](https://developer
|
|||
* [Pablo Curiel (DarkMatterCore)](https://github.com/DarkMatterCore)
|
||||
* [wolfposd](https://github.com/wolfposd)
|
||||
* [agungrbudiman](https://github.com/agungrbudiman)
|
||||
* Perfect algorithms and great examples taken from mrdude project [mrdude2478/IPS_Patch_Creator](https://github.com/mrdude2478/IPS_Patch_Creator/)
|
||||
|
||||
* French by [Stephane Meden (JackFromNice)](https://github.com/JackFromNice)
|
||||
* Italian by [unbranched](https://github.com/unbranched)
|
||||
* Korean by [DDinghoya](https://github.com/DDinghoya)
|
||||
* Portuguese by [almircanella](https://github.com/almircanella)
|
||||
* Spanish by [/u/cokimaya007](https://www.reddit.com/u/cokimaya007), [Kuziel Alejandro](https://github.com/Uzi-Oni)
|
||||
* Chinese (Simplified) by [Huang YunKun (htynkn)](https://github.com/htynkn), [FFT9 (XXgame Group)](http://xxgame.net/)
|
||||
* Chinese (Traditional) by [qazrfv1234](https://github.com/qazrfv1234), [FFT9 (XXgame Group)](http://xxgame.net/)
|
||||
* Chinese (Simplified) by [Huang YunKun (htynkn)](https://github.com/htynkn), [FFT9 (XXgame Group)](https://www.xxgame.net)
|
||||
* Chinese (Traditional) by [qazrfv1234](https://github.com/qazrfv1234), [FFT9 (XXgame Group)](https://www.xxgame.net)
|
||||
* German by [Swarsele](https://github.com/Swarsele)
|
||||
* Vietnamese by [Hai Phan Nguyen (pnghai)](https://github.com/pnghai)
|
||||
* Czech by [Spenaat](https://github.com/spenaat)
|
||||
* Arabic by [eslamabdel](https://github.com/eslamabdel)
|
||||
* Romanian by [Călin Ilie](https://github.com/calini)
|
||||
* Swedish by [Daniel Nylander](https://github.com/yeager)
|
||||
* Japanese by [kuragehime](https://github.com/kuragehimekurara1)
|
||||
* Ryukyuan languages by [kuragehime](https://github.com/kuragehimekurara1)
|
||||
|
||||
* Angelo Elias Dalzotto makes packages in AUR
|
||||
* Phoenix[Msc] provides his shiny Mac M1 for debug
|
||||
* Swedish by [Daniel Nylander](https://github.com/yeager) - (coming soon)
|
||||
|
||||
### System requirements
|
||||
|
||||
- JDK 11 for macOS and Linux
|
||||
- libusb, if you have a Mac with Apple Silicon (install via `brew install libusb`)
|
||||
JRE/JDK 8u60 or higher for Windows
|
||||
|
||||
### Supported Goldleaf versions
|
||||
| Goldleaf version | NS-USBloader version |
|
||||
JDK 11 for MacOS and Linux
|
||||
|
||||
### Supported GoldLeaf versions
|
||||
| GoldLeaf version | NS-USBloader version |
|
||||
|------------------|----------------------|
|
||||
| v0.5 | v0.4 - v0.5.2, v0.8+ |
|
||||
| v0.6 | none |
|
||||
| v0.6.1 | v0.6 |
|
||||
| v0.7 - 0.7.3 | v0.7+ |
|
||||
| v0.8 - 0.9 | v1.0+ |
|
||||
| v0.10 | v6.0+ |
|
||||
| v0.10 | v6.0 |
|
||||
|
||||
where '+' means 'any next NS-USBloader version'.
|
||||
|
||||
|
@ -122,23 +117,24 @@ Double-click on downloaded .jar file. Follow instructions. Or see 'Linux' sectio
|
|||
|
||||
Set 'Security & Privacy' settings if needed.
|
||||
|
||||
*Please note: JDK 19 is recommended for using on macOS. There are issues already reported from users on Mac with JDK 14.*
|
||||
*Please note: JDK 11 is recommended for using on MacOS (EXCEPT APPLE SILICON). There are few really weird issues already reported from JDK 14 users on Mac.*
|
||||
|
||||
##### macOS on Apple Silicon (ARM)
|
||||
|
||||
Download application with `-m1.jar` postfix.
|
||||
|
||||
Manually install libusb with Homebrew by running `brew install libusb` in your Terminal.
|
||||
* Some users [tested](https://github.com/developersu/ns-usbloader/issues/91) this application with [Zulu-JDK with FX support](https://www.azul.com/downloads/zulu-community/?version=java-11-lts&os=macos&architecture=arm-64-bit&package=jdk-fx). Try it!
|
||||
* OpenJDK 17 also should be a working solution. [Tell us if it works for you!]((https://github.com/developersu/ns-usbloader/issues/91))
|
||||
|
||||
##### Windows:
|
||||
|
||||
* [Download and install Java JRE](http://java.com/download/) (8u60 or higher)
|
||||
* Get this application (JAR file) and double-click on it (alternatively open 'cmd', go to place where jar located and execute via `java -jar thisAppName.jar`)
|
||||
* Once application opens click on 'Gear' icon.
|
||||
* Click 'Download and install drivers'
|
||||
* Install drivers
|
||||
|
||||
#### And how to use it?
|
||||
|
||||
The first thing you should do it install Awoo ([Huntereb](https://github.com/Huntereb/Awoo-Installer)) or Goldleaf ([XorTroll](https://github.com/XorTroll/Goldleaf)) on your NS.
|
||||
The first thing you should do it install Awoo ([Huntereb](https://github.com/Huntereb/Awoo-Installer)) or GoldLeaf ([XorTroll](https://github.com/XorTroll/Goldleaf)) on your NS.
|
||||
|
||||
Take a look on app, find where is the option to install from USB and/or Network. Maybe (very old) [this article (about TinFoil)](https://developersu.blogspot.com/2019/02/ns-usbloader-en.html) will be helpful.
|
||||
|
||||
|
@ -148,19 +144,19 @@ There are three tabs. First one is main.
|
|||
|
||||
##### 'Gamepad' tab.
|
||||
|
||||
At the top of you selecting from drop-down application and protocol that you're going to use. For Goldleaf only USB is available. Lamp icon stands for switching themes (light or dark).
|
||||
At the top of you selecting from drop-down application and protocol that you're going to use. For GoldLeaf only USB is available. Lamp icon stands for switching themes (light or dark).
|
||||
|
||||
Then you may drag-n-drop files (split-files aka folders) to application or use 'Select NSP files' button. Multiple selection for files available. Click it again and select files from another folder it you want, it will be added into the table.
|
||||
|
||||
Table.
|
||||
|
||||
There you can select checkbox for files that will be sent to application (AW/GL). ~~Since Goldleaf v0.5 allow you only one file transmission per time, only one file is available for selection.~~
|
||||
There you can select checkbox for files that will be sent to application (AW/GL). ~~Since GoldLeaf v0.5 allow you only one file transmission per time, only one file is available for selection.~~
|
||||
|
||||
Also, you can use space to select/un-select files and 'delete' button for deleting. By right-mouse-click you can see context menu where you can delete one OR all items from the table.
|
||||
Also you can use space to select/un-select files and 'delete' button for deleting. By right-mouse-click you can see context menu where you can delete one OR all items from the table.
|
||||
|
||||
For Goldleaf v0.6.1 and NS-USBloader v0.6 (and higher) you will have to use 'Explore content' -> 'Remote PC (via USB)' You will see two drives HOME:/ and VIRT:/. First drive is pointing to your home directory. Second one is reflection of what you've added to table (first application tab). Also VIRT:/ drive have limited functionality in comparison to HOME:/. E.g. you can't write files to this drive since it's not a drive. But don't worry, it won't make any impact on Goldleaf or your NS if you try.
|
||||
For GoldLeaf v0.6.1 and NS-USBloader v0.6 (and higher) you will have to use 'Explore content' -> 'Remote PC (via USB)' You will see two drives HOME:/ and VIRT:/. First drive is pointing to your home directory. Second one is reflection of what you've added to table (first application tab). Also VIRT:/ drive have limited functionality in comparison to HOME:/. E.g. you can't write files to this drive since it's not a drive. But don't worry, it won't make any impact on GoldLeaf or your NS if you try.
|
||||
|
||||
Also, for Goldleaf write files (from NS to PC): You have to 'Stop execution' properly before accessing files transferred from GL. Usually you have to wait 5sec or less. It will guarantee that your files properly written to PC.
|
||||
Also, for GoldLeaf write files (from NS to PC): You have to 'Stop execution' properly before accessing files transferred from GL. Usually you have to wait 5sec or less. It will guarantee that your files properly written to PC.
|
||||
|
||||
##### 'RCM' tab
|
||||
|
||||
|
@ -176,7 +172,7 @@ Here you can configure settings for network file transmission. Usually you shoul
|
|||
|
||||
Also here you can:
|
||||
* Set 'Auto-check for updates' for checking for updates when application starts, or click button to verify if new version released immediately.
|
||||
* Set 'Show only *.nsp in Goldleaf' to filter all files displayed at HOME:/ drive. So only NSP files will appear.
|
||||
* Set 'Show only *.nsp in GoldLeaf' to filter all files displayed at HOME:/ drive. So only NSP files will appear.
|
||||
|
||||
##### 'Dialog with three dots' tab.
|
||||
|
||||
|
@ -189,7 +185,7 @@ To get help run ``$ java -jar ns-usbloader-4.0.jar --help``
|
|||
|
||||
```
|
||||
-c,--clean Remove/reset settings and exit
|
||||
-g,--Goldleaf <...> Install via Goldleaf mode. Check '-g help' for information.
|
||||
-g,--goldleaf <...> Install via GoldLeaf mode. Check '-g help' for information.
|
||||
-h,--help Show this help
|
||||
-m,--merge <...> Merge files. Check '-m help' for information.
|
||||
-n,--tfn <...> Install via Awoo Network mode. Check '-n help' for information.
|
||||
|
@ -220,7 +216,7 @@ Send RCM payload:
|
|||
$ java -jar ns-usbloader-4.0.jar -r C:\Users\Superhero\hekate.bin
|
||||
Send files to Awoo Installer via Net-install:
|
||||
$ java -jar ns-usbloader-4.0.jar -n nsip=192.168.0.1 ./file.nsz ./file.nsp ~/*.xci
|
||||
Send files to Goldleaf v0.8:
|
||||
Send files to GoldLeaf v0.8:
|
||||
$ java -jar ns-usbloader-4.0.jar -g ver=v0.8 ./*
|
||||
Split files:
|
||||
$ java -jar ns-usbloader-4.0.jar -s /tmp/ ~/*.nsp
|
||||
|
@ -231,14 +227,14 @@ $ java -jar ns-usbloader-4.0.jar -m /tmp/ ~/*.nsp
|
|||
### Other notes
|
||||
|
||||
'Status' = 'Uploaded' that appears in the table does not mean that file has been installed. It means that it has been sent to NS without any issues! That's what this app about.
|
||||
Handling successful/failed installation is a purpose of the other side application: Awoo/Awoo-like or Goldleaf. And they don't provide any feedback interfaces so I can't detect success/failure.
|
||||
Handling successful/failed installation is a purpose of the other side application: Awoo/Awoo-like or GoldLeaf. And they don't provide any feedback interfaces so I can't detect success/failure.
|
||||
|
||||
#### What is this '-legacy' jar?!
|
||||
|
||||
**JAR with NO postfixes** recommended for Windows users, Linux users and macOS users who're using Mojave or later versions.
|
||||
**JAR with NO postfixes** recommended for Windows users, Linux users and MacOS users who're using Mojave or later versions.
|
||||
|
||||
**JAR with '-legacy' postfix** is for macOS users who're still using OS X releases before (!) Mojave.
|
||||
(It also works for Linux and for Windows, but sometimes it doesn't work for Windows and I don't know why).
|
||||
**JAR with '-legacy' postfix** is for MacOS users who're still using OS X releases before (!) Mojave.
|
||||
(It also works for Linux and for Windows but sometimes it doesn't work for Windows and I don't know why).
|
||||
|
||||
We have this situation because of weird behaviour inside usb4java library used in this application for USB interactions. In '-legacy' it's v1.2.0 and in 'normal' it's v1.3.0
|
||||
|
||||
|
@ -258,14 +254,17 @@ This is non-commercial project.
|
|||
|
||||
Nevertheless, I'll be more than happy if you find a chance to make a donation for charity to people I trust:
|
||||
|
||||
* BTC → 1BnErE3n6LEdEjvvFrt4FMdXd1UGa5L7Ge
|
||||
* ETH → 0x9c29418129553bE171181bb6245151aa0576A3b7
|
||||
* DOT → 15BWSwmA4xEHZdq3gGftWg7dctMQk9vXwqA92Pg22gsxDweF
|
||||
* LTC → ltc1qfjvzxm04tax077ra9rvmxdnsum8alws2n20fag
|
||||
* ETC → 0xe9064De288C8454942533a005AB72515e689226E
|
||||
* USDT (TRC20) → TKgp5SvJGiqYNFtvJfEDGLFbezFEHq1tBy
|
||||
* USDT (ERC20) → 0x9c29418129553bE171181bb6245151aa0576A3b7
|
||||
* XRP → rGmGaLsKmSUbxWfyi4mujtVamTzj3Nqxbw.
|
||||
* BTC → bc1q67j4yjmt67mes0hv03fyydjejmw6ahw0v932su
|
||||
* ETH → 0x82Ab0ddE183C12cAa6eD61DF3671675C4bdC42fc
|
||||
* DOGE → D8o42b952yjEWZ5Ajq4ZtjGvx1kR7DyDHm
|
||||
* DOT → 1511KQqm6Mme5Za4rtgsSdzCyuEzQ6CC1a6XLxQJXXW3GWpo
|
||||
* LTC → LRFXTN4rTEiQ3RxzssMFC5S1WMRd1raN2Q
|
||||
* LUNA → terra1n0sfmljpuu87h7lrn9nzxadfa3qxthlmvtq5lf
|
||||
* TRX → TU3AyFkF12Jg1yApcXGz91R8xKvXV1EzkW
|
||||
* ETC → 0x78A946fC9708c024298c9a4f8961A49B7a830d53
|
||||
* USDT (TRC20) → TU3AyFkF12Jg1yApcXGz91R8xKvXV1EzkW
|
||||
* USDT (ERC20) → 0x82Ab0ddE183C12cAa6eD61DF3671675C4bdC42fc
|
||||
* XRP → r91kfRiRsvnDp7evHNmXkrL3yAL7eakWk1
|
||||
|
||||
Thanks!
|
||||
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
#!/usr/bin/env xdg-open
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=NS-USBloader
|
||||
Exec=ns-usbloader
|
||||
Comment=NS multi tool
|
||||
Terminal=false
|
||||
Icon=ns-usbloader.svg
|
||||
Categories=Game;
|
|
@ -1,118 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="45mm"
|
||||
height="45mm"
|
||||
viewBox="0 0 45.000001 45"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||
sodipodi:docname="ns-usbloader.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.6568543"
|
||||
inkscape:cx="206.82873"
|
||||
inkscape:cy="90.421279"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="svg8"
|
||||
showgrid="false"
|
||||
units="mm"
|
||||
inkscape:window-width="3754"
|
||||
inkscape:window-height="2127"
|
||||
inkscape:window-x="1166"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid829"
|
||||
originx="-40.993993"
|
||||
originy="-37.999754" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="g851"
|
||||
inkscape:label="mainGRP"
|
||||
transform="translate(-40.993968,-26.999903)">
|
||||
<path
|
||||
id="path847"
|
||||
transform="scale(0.26458333)"
|
||||
d="m 188.97656,102.04688 c -18.97637,0 -34.01562,18.70089 -34.01562,30.23632 -0.0219,42.2441 -0.0386,69.16374 0,109.60742 0,11.85827 15.03925,30.23633 34.01562,30.23633 h 48.94141 V 102.04688 Z"
|
||||
style="fill:#00c8fc;fill-opacity:1;stroke-width:1"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="con" />
|
||||
<path
|
||||
id="rect823"
|
||||
d="m 64.973294,26.999903 v 45 h 21.02 v -45 z"
|
||||
style="fill:#ec0000;fill-opacity:1;stroke-width:0.116442"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="big" />
|
||||
</g>
|
||||
<path
|
||||
id="path862"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.392613"
|
||||
d="m 11.547015,28.4105 a 2.1593723,2.1593723 0 0 0 -2.2000565,2.117691 2.1593723,2.1593723 0 0 0 2.1176905,2.200059 2.1593723,2.1593723 0 0 0 2.200555,-2.1167 2.1593723,2.1593723 0 0 0 -2.1167,-2.20105 l -0.04267,2.158874 z m 3.840427,-3.937182 a 2.1593723,2.1593723 0 0 0 -2.199561,2.117693 2.1593723,2.1593723 0 0 0 2.117195,2.200057 2.1593723,2.1593723 0 0 0 2.200555,-2.117195 2.1593723,2.1593723 0 0 0 -2.1167,-2.200555 l -0.04217,2.158876 z m -7.6809635,0 a 2.1593722,2.1593722 0 0 0 -2.200057,2.117693 2.1593722,2.1593722 0 0 0 2.117691,2.200057 2.1593722,2.1593722 0 0 0 2.200554,-2.117195 2.1593722,2.1593722 0 0 0 -2.117195,-2.200555 l -0.04218,2.158876 z m 3.8405365,-3.938173 a 2.1593723,2.1593723 0 0 0 -2.2000565,2.117691 2.1593723,2.1593723 0 0 0 2.1176905,2.200059 2.1593723,2.1593723 0 0 0 2.200555,-2.1167 2.1593723,2.1593723 0 0 0 -2.1167,-2.20105 l -0.04267,2.158874 z"
|
||||
inkscape:label="small_c"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
inkscape:label="slogan"
|
||||
id="layer1"
|
||||
transform="translate(-40.993968,-213.9999)"
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
aria-label="everywhere"
|
||||
transform="matrix(0.26458333,0,0,0.26458333,-24.077084,181.70833)"
|
||||
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:35.0667px;line-height:1.25;font-family:Raleway;-inkscape-font-specification:'Raleway, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none"
|
||||
id="flowRoot1022"
|
||||
inkscape:label="flowRoot1022"
|
||||
inkscape:groupmode="layer" />
|
||||
</g>
|
||||
<path
|
||||
id="path853"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.272727"
|
||||
d="m 11.506852,6.300096 a 4.5000001,4.5000001 0 0 1 4.49918,4.500616 4.5000001,4.5000001 0 0 1 -4.500411,4.499384 4.5000001,4.5000001 0 0 1 -4.4995895,-4.500205 4.5000001,4.5000001 0 0 1 4.5000005,-4.499795"
|
||||
inkscape:label="big_c"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
id="path1334"
|
||||
d="m 35.091899,7.050931 -1.966235,3.404775 h 1.402615 v 17.402765 l -3.579993,-3.388515 c -0.231149,-0.288377 -0.393301,-0.665687 -0.402284,-1.053816 0,-1.570143 -3.97e-4,-2.502567 -9.76e-4,-2.845788 0.662828,-0.232646 1.141253,-0.857572 1.141253,-1.600489 0,-0.939842 -0.76265,-1.702559 -1.702831,-1.702559 -0.940589,0 -1.702967,0.76265 -1.702967,1.702559 0,0.742917 0.478154,1.367843 1.140438,1.600489 l -4.76e-4,2.812447 c 0,0.762241 0.418205,1.560957 0.90847,2.069322 -0.01456,-0.01388 -0.03007,-0.02831 2.83e-4,8.15e-4 0.01211,0.01075 3.797875,3.595101 3.797875,3.595101 0.230809,0.287762 0.39194,0.664868 0.401196,1.052727 v 1.968677 c -1.30057,0.260954 -2.28042,1.409421 -2.28042,2.787065 0,1.570687 1.273194,2.843881 2.843405,2.843881 1.570686,0 2.843946,-1.273194 2.843946,-2.843881 0,-1.377917 -0.980663,-2.526381 -2.282303,-2.787335 v -1.934186 c 0,-0.005 2.59e-4,-0.0099 0,-0.01498 v -4.278078 c 0.0098,-0.38711 0.171203,-0.763741 0.402285,-1.051231 0,0 3.785488,-3.583532 3.797733,-3.594625 0.03043,-0.02872 0.01454,-0.01444 2.59e-4,-2.58e-4 0.490197,-0.508364 0.908134,-1.307418 0.908134,-2.069798 l -3.97e-4,-2.710376 h 1.141588 v -3.405646 h -3.405338 v 3.405663 h 1.140097 c 0,0 -0.0012,0.713861 -0.0012,2.743583 -0.0089,0.388196 -0.170862,0.765917 -0.402012,1.054155 l -3.580815,3.389238 V 10.455706 h 1.404858 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#ffffff;stroke-width:0.0680452"
|
||||
inkscape:label="usb_logo" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:0.264583"
|
||||
d="m 21.967046,0 c -0.0065,-1.9994448e-6 -0.01188,0.0054 -0.01188,0.01188 v 44.976581 c 0,0.0065 0.0054,0.01188 0.01188,0.01188 h 2.000395 c 0.0065,0 0.01188,-0.0054 0.01188,-0.01188 V 0.011885 c 0,-0.0065 -0.0054,-0.011879999445 -0.01188,-0.011879999445 z"
|
||||
id="rect1136"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csssssssc" />
|
||||
</svg>
|
Before Width: | Height: | Size: 6.5 KiB |
|
@ -1,8 +0,0 @@
|
|||
#### How to prepare JRE from JDK to bundle it with application
|
||||
|
||||
1. Run `java --list-modules`
|
||||
2. Update resulting list s/@.*\n/\,/g
|
||||
3. Run `jlink --no-header-files --no-man-pages --compress=2 --add-modules !!!_PASTE_RESULT_HERE_!!! --output jre`
|
||||
4. JRE created at folder 'jre
|
||||
|
||||
jlink --no-header-files --no-man-pages --compress=2 --add-modules $($(java --list-modules) -join "," -replace "@[0-9].*") --output jre-11'
|
|
@ -1,160 +0,0 @@
|
|||
;Include Modern UI
|
||||
!include "MUI.nsh"
|
||||
Unicode true
|
||||
;Name and file
|
||||
|
||||
!define APPNAME "NS-USBloader"
|
||||
!define COMPANYNAME "Dmitry Isaenko"
|
||||
!define VERSIONMAJOR 0
|
||||
!define VERSIONMINOR 0
|
||||
!define VERSIONBUILD 0
|
||||
|
||||
Name "NS-USBloader"
|
||||
OutFile "Installer.exe"
|
||||
|
||||
;Default installation folder
|
||||
InstallDir "$PROGRAMFILES\${APPNAME}"
|
||||
|
||||
;Get installation folder from registry if available
|
||||
InstallDirRegKey HKCU "Software\${APPNAME}" ""
|
||||
|
||||
;Request application privileges for Windows Vista
|
||||
RequestExecutionLevel admin
|
||||
|
||||
!define MUI_ICON installer_logo.ico
|
||||
!define MUI_UNICON uninstaller_logo.ico
|
||||
; !define MUI_FINISHPAGE_NOAUTOCLOSE
|
||||
|
||||
!define MUI_WELCOMEFINISHPAGE_BITMAP "leftbar.bmp"
|
||||
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "leftbar_uninstall.bmp"
|
||||
|
||||
!define MUI_FINISHPAGE_LINK "NS-USBloader at GitHub"
|
||||
!define MUI_FINISHPAGE_LINK_LOCATION https://github.com/developersu/NS-USBloader/
|
||||
|
||||
!define MUI_FINISHPAGE_RUN "$INSTDIR\NS-USBloader.exe"
|
||||
!define MUI_FINISHPAGE_SHOWREADME
|
||||
!define MUI_FINISHPAGE_SHOWREADME_TEXT $(l10n_CreateShortcut)
|
||||
!define MUI_FINISHPAGE_SHOWREADME_FUNCTION CreateDesktopShortCut
|
||||
!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
|
||||
;--------------------------------
|
||||
;Interface Settings
|
||||
|
||||
!define MUI_ABORTWARNING
|
||||
;--------------------------------
|
||||
;Language Selection Dialog Settings
|
||||
|
||||
;Remember the installer language
|
||||
!define MUI_LANGDLL_REGISTRY_ROOT "HKCU"
|
||||
!define MUI_LANGDLL_REGISTRY_KEY "Software\${APPNAME}"
|
||||
!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
|
||||
|
||||
;--------------------------------
|
||||
;Pages
|
||||
;!define MUI_HEADERIMAGE
|
||||
;!define MUI_HEADERIMAGE_RIGHTi
|
||||
;!define MUI_HEADERIMAGE_BITMAP "install_header.bmp"
|
||||
;!define MUI_HEADERIMAGE_UNBITMAP "install_header.bmp"
|
||||
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
!insertmacro MUI_PAGE_LICENSE "license.txt"
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
|
||||
!insertmacro MUI_UNPAGE_CONFIRM
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
!insertmacro MUI_UNPAGE_FINISH
|
||||
|
||||
;--------------------------------
|
||||
;Languages
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
!insertmacro MUI_LANGUAGE "Russian"
|
||||
!insertmacro MUI_LANGUAGE "SpanishInternational"
|
||||
!insertmacro MUI_LANGUAGE "SimpChinese"
|
||||
!insertmacro MUI_LANGUAGE "TradChinese"
|
||||
!insertmacro MUI_LANGUAGE "Japanese"
|
||||
!insertmacro MUI_LANGUAGE "Korean"
|
||||
!insertmacro MUI_LANGUAGE "Italian"
|
||||
!insertmacro MUI_LANGUAGE "PortugueseBR"
|
||||
!insertmacro MUI_LANGUAGE "Vietnamese"
|
||||
!insertmacro MUI_LANGUAGE "Arabic"
|
||||
!insertmacro MUI_LANGUAGE "Czech"
|
||||
!insertmacro MUI_LANGUAGE "Romanian"
|
||||
!insertmacro MUI_LANGUAGE "French"
|
||||
!insertmacro MUI_LANGUAGE "Swedish"
|
||||
|
||||
;Language strings
|
||||
LangString l10n_CreateShortcut ${LANG_ENGLISH} "Create Desktop Shortcut"
|
||||
LangString l10n_CreateShortcut ${LANG_RUSSIAN} "Создать ярлык на Рабочем столе"
|
||||
|
||||
;--------------------------------
|
||||
Section "NS-USBloader" Install
|
||||
|
||||
SetOutPath "$INSTDIR"
|
||||
file /r jdk
|
||||
file Drivers_set.exe
|
||||
file NS-USBloader.exe
|
||||
file logo.ico
|
||||
|
||||
; Registry information for add/remove programs
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\""
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayIcon" "$\"$INSTDIR\logo.ico$\""
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "Publisher" "$\"${COMPANYNAME}$\""
|
||||
|
||||
; Start Menu
|
||||
CreateDirectory "$SMPROGRAMS\${APPNAME}"
|
||||
CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\NS-USBloader.exe" "" "$INSTDIR\logo.ico"
|
||||
CreateShortCut "$SMPROGRAMS\${APPNAME}\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
|
||||
|
||||
;Store installation folder
|
||||
WriteRegStr HKCU "Software\${APPNAME}" "" $INSTDIR
|
||||
|
||||
;Create uninstaller
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
|
||||
SectionEnd
|
||||
;--------------------------------
|
||||
;Installer Functions
|
||||
|
||||
Function .onInit
|
||||
; set mandatory installation rule to section
|
||||
SectionSetFlags ${Install} 17
|
||||
FunctionEnd
|
||||
|
||||
Function un.onInit
|
||||
!insertmacro MUI_UNGETLANGUAGE
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Function CreateDesktopShortCut
|
||||
CreateShortcut "$DESKTOP\NS-USBloader.lnk" "$INSTDIR\NS-USBloader.exe"
|
||||
FunctionEnd
|
||||
|
||||
;--------------------------------
|
||||
;Uninstaller Section
|
||||
|
||||
Section "Uninstall"
|
||||
|
||||
; Start Menu
|
||||
Delete "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk"
|
||||
Delete "$SMPROGRAMS\${APPNAME}\Uninstall.lnk"
|
||||
Delete "$DESKTOP\NS-USBloader.lnk"
|
||||
rmDir "$SMPROGRAMS\${APPNAME}"
|
||||
|
||||
;Delete installed files
|
||||
RMDir /r "$INSTDIR\jdk\*"
|
||||
Delete "$INSTDIR\Drivers_set.exe"
|
||||
Delete "$INSTDIR\NS-USBloader.exe"
|
||||
Delete "$INSTDIR\logo.ico"
|
||||
Delete "$SMPROGRAMS\Uninstall.exe"
|
||||
|
||||
RMDir "$INSTDIR"
|
||||
|
||||
DeleteRegKey /ifempty HKCU "Software\${APPNAME}"
|
||||
; Cleanup records stored for uninstaller from the registry
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}"
|
||||
|
||||
SectionEnd
|
||||
;--------------------------------
|
||||
;Uninstaller Functions
|
Before Width: | Height: | Size: 125 KiB |
Before Width: | Height: | Size: 151 KiB |
Before Width: | Height: | Size: 151 KiB |
Before Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 114 KiB |
|
@ -1,13 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
TIMESTAMP=`date +%Y%m%d.%H%M%S`
|
||||
VERSIONMAJOR=`grep '<version>' pom.xml | head -1 | sed -e 's/^.*<version>//g' -e 's/\..*$//g'`
|
||||
VERSIONMINOR=`grep '<version>' pom.xml | head -1 | sed -E 's/^.*<version>[0-9]+?\.//g' | sed -E -e 's/(\..*|-SNAPSHOT|)<\/version>.*$//g'`
|
||||
sed -z -i -e "s/!define\ VERSIONMAJOR\ [0-9]/!define\ VERSIONMAJOR $VERSIONMAJOR\ /" misc/windows/NSIS/installer.nsi
|
||||
sed -z -i -e "s/!define\ VERSIONMINOR\ [0-9]/!define\ VERSIONMINOR $VERSIONMINOR\ /" misc/windows/NSIS/installer.nsi
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
sed -z -i -e "s/OutFile\ \"Installer.exe\"/OutFile\ \"Installer-$VERSIONMAJOR.$VERSIONMINOR-$TIMESTAMP.exe\"\ /" misc/windows/NSIS/installer.nsi
|
||||
else
|
||||
sed -z -i -e "s/OutFile\ \"Installer-$VERSIONMAJOR.$VERSIONMINOR-[0-9]*\.[0-9]*.exe\"/OutFile\ \"Installer-legacy-$VERSIONMAJOR.$VERSIONMINOR-$TIMESTAMP.exe\"\ /" misc/windows/NSIS/installer.nsi
|
||||
fi
|
138
pom.xml
|
@ -8,10 +8,12 @@
|
|||
<name>NS-USBloader</name>
|
||||
|
||||
<artifactId>ns-usbloader</artifactId>
|
||||
<version>7.1</version> <!-- linked via script to NSIS system. Should have format of 2 blocks of numbers -->
|
||||
<version>6.1</version>
|
||||
|
||||
<url>https://redrise.ru</url>
|
||||
<description>NS multi-tool</description>
|
||||
<description>
|
||||
NS multi-tool
|
||||
</description>
|
||||
<inceptionYear>2019</inceptionYear>
|
||||
<organization>
|
||||
<name>Dmitry Isaenko</name>
|
||||
|
@ -38,25 +40,16 @@
|
|||
</developer>
|
||||
</developers>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>redrise</id>
|
||||
<name>redrise.ru repository</name>
|
||||
<url>https://repo.redrise.ru/releases</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.build.timestamp.format>yyyyMMdd.HHmmss</maven.build.timestamp.format>
|
||||
<javafx.version>19.0.2.1</javafx.version>
|
||||
<maven.compiler.release>11</maven.compiler.release>
|
||||
</properties>
|
||||
|
||||
<issueManagement>
|
||||
<system>GitHub</system>
|
||||
<url>https://github.com/developersu/${project.artifactId}/issues</url>
|
||||
<url>https://github.com/developer_su/${project.artifactId}/issues</url>
|
||||
</issueManagement>
|
||||
<!-- openJFX Linux -->
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
|
||||
<dependency>
|
||||
|
@ -65,69 +58,89 @@
|
|||
<version>1.5.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- openJFX Linux -->
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-graphics</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>18.0.1</version>
|
||||
<classifier>linux</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<artifactId>javafx-media</artifactId>
|
||||
<version>18.0.1</version>
|
||||
<classifier>linux</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<version>18.0.1</version>
|
||||
<classifier>linux</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-graphics</artifactId>
|
||||
<version>18.0.1</version>
|
||||
<classifier>linux</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- openJFX Windows -->
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-graphics</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>18.0.1</version>
|
||||
<classifier>win</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<artifactId>javafx-media</artifactId>
|
||||
<version>18.0.1</version>
|
||||
<classifier>win</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<version>18.0.1</version>
|
||||
<classifier>win</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-graphics</artifactId>
|
||||
<version>18.0.1</version>
|
||||
<classifier>win</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- openJFX MAC -->
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-graphics</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>18.0.1</version>
|
||||
<classifier>mac</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-controls</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<artifactId>javafx-media</artifactId>
|
||||
<version>18.0.1</version>
|
||||
<classifier>mac</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-fxml</artifactId>
|
||||
<version>${javafx.version}</version>
|
||||
<version>18.0.1</version>
|
||||
<classifier>mac</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-graphics</artifactId>
|
||||
<version>18.0.1</version>
|
||||
<classifier>mac</classifier>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
@ -157,13 +170,6 @@
|
|||
<version>5.9.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- redrise repository -->
|
||||
<dependency>
|
||||
<groupId>ru.redrise</groupId>
|
||||
<artifactId>libKonogonka</artifactId>
|
||||
<version>0.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<finalName>${project.artifactId}-${project.version}-${maven.build.timestamp}</finalName>
|
||||
|
@ -179,16 +185,6 @@
|
|||
</resources>
|
||||
|
||||
<plugins>
|
||||
<!--OpenJFX for Java9+
|
||||
<plugin>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-maven-plugin</artifactId>
|
||||
<version>0.0.8</version>
|
||||
<configuration>
|
||||
<mainClass>nsusbloader.NSLMain</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
-->
|
||||
<!-- Junit5 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
@ -203,23 +199,17 @@
|
|||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.10.1</version>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<release>11</release>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Don't generate default JAR without dependencies -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.2</version>
|
||||
<!--
|
||||
<configuration>
|
||||
<manifestEntries>
|
||||
<Automatic-Module-Name>nsusbloader</Automatic-Module-Name>
|
||||
</manifestEntries>
|
||||
</configuration>
|
||||
-->
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-jar</id>
|
||||
|
@ -253,13 +243,14 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Launch4j
|
||||
<plugin>
|
||||
<groupId>com.akathist.maven.plugins.launch4j</groupId>
|
||||
<version>2.2.0</version>
|
||||
<version>1.7.25</version>
|
||||
<artifactId>launch4j-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>l4j-ns-usbloader</id>
|
||||
<id>l4j-NS-USBloader</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>launch4j</goal>
|
||||
|
@ -267,37 +258,34 @@
|
|||
<configuration>
|
||||
<headerType>gui</headerType>
|
||||
<icon>appicon.ico</icon>
|
||||
<outfile>target/${project.name}.exe</outfile>
|
||||
<jar>target/${project.artifactId}-${project.version}-${maven.build.timestamp}.jar</jar>
|
||||
<!-- <downloadUrl>https://download.oracle.com/java/17/archive/jdk-17.0.1_windows-x64_bin.msi</downloadUrl> -->
|
||||
<errTitle>Launching error</errTitle>
|
||||
<!-- <dontWrapJar>true</dontWrapJar> -->
|
||||
<outfile>target/NS-USBloader-${project.version}.exe</outfile>
|
||||
<jar>target/ns-usbloader-${project.version}-jar-with-dependencies.jar</jar>
|
||||
<errTitle>NS-USBloader</errTitle>
|
||||
<classPath>
|
||||
<mainClass>nsusbloader.Main</mainClass>
|
||||
<addDependencies>false</addDependencies>
|
||||
<preCp>anything</preCp>
|
||||
</classPath>
|
||||
<jre>
|
||||
<path>%PWD%/jdk</path>
|
||||
<minVersion>11.0.0</minVersion>
|
||||
<minVersion>1.8</minVersion>
|
||||
</jre>
|
||||
<versionInfo>
|
||||
<fileVersion>${project.version}.0.0</fileVersion>
|
||||
<fileVersion>1.0.0.0</fileVersion>
|
||||
<txtFileVersion>${project.version}</txtFileVersion>
|
||||
<fileDescription>NS multi-tool</fileDescription>
|
||||
<copyright>GNU General Public License v3, ${project.inceptionYear} ${project.organization.name}, Russia.</copyright>
|
||||
<productVersion>${project.version}.0.0</productVersion>
|
||||
<fileDescription>Awoo and GoldLeaf installer for your NS</fileDescription>
|
||||
<copyright>GNU General Public License v3, 2019 ${project.organization.name}. Russia/LPR.</copyright>
|
||||
<productVersion>1.0.0.0</productVersion>
|
||||
<txtProductVersion>${project.version}</txtProductVersion>
|
||||
<companyName>${project.organization.name}</companyName>
|
||||
<productName>${project.name}</productName>
|
||||
<internalName>${project.name}</internalName>
|
||||
<originalFilename>${project.name}.exe</originalFilename>
|
||||
</versionInfo>
|
||||
<messages>
|
||||
<startupErr>Startup error</startupErr>
|
||||
<jreNotFoundErr>JDK not found</jreNotFoundErr>
|
||||
<jreVersionErr>JDK Version mismatch</jreVersionErr>
|
||||
<launcherErr>Launcher Error</launcherErr>
|
||||
</messages>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
-->
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -1,19 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="132.50603mm"
|
||||
height="45.000351mm"
|
||||
viewBox="0 0 132.50603 45.000351"
|
||||
height="58.000351mm"
|
||||
viewBox="0 0 132.50603 58.000351"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||
sodipodi:docname="Application Logo.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||
sodipodi:docname="Application Logo.svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
|
@ -23,31 +23,28 @@
|
|||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4.0000001"
|
||||
inkscape:cx="233.49999"
|
||||
inkscape:cy="127.875"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="383.67648"
|
||||
inkscape:cy="100.29922"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="flowRoot1022"
|
||||
inkscape:current-layer="svg8"
|
||||
showgrid="false"
|
||||
units="mm"
|
||||
inkscape:window-width="3754"
|
||||
inkscape:window-height="2127"
|
||||
inkscape:window-x="1166"
|
||||
inkscape:window-width="1860"
|
||||
inkscape:window-height="1058"
|
||||
inkscape:window-x="1980"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:showpageshadow="0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1">
|
||||
inkscape:document-rotation="0">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid829"
|
||||
originx="-40.99399"
|
||||
originy="-37.999752" />
|
||||
originx="-40.993969"
|
||||
originy="-37.999746" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
|
@ -57,6 +54,7 @@
|
|||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
|
@ -116,65 +114,145 @@
|
|||
inkscape:connector-curvature="0"
|
||||
style="fill:#ffffff;stroke-width:0.0680452"
|
||||
inkscape:label="usb_logo" />
|
||||
<g
|
||||
aria-label="NS-USBloader"
|
||||
transform="scale(0.97866107,1.0218042)"
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:1.43163px;line-height:1.25;font-family:Play;-inkscape-font-specification:'Play, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.357908"
|
||||
x="47.959785"
|
||||
y="17.188828"
|
||||
id="text982"
|
||||
style="font-size:1.43163px;line-height:1.25;font-family:Play;-inkscape-font-specification:'Play, Normal';letter-spacing:0px;word-spacing:0px;fill:#ffffff;stroke-width:0.357908"
|
||||
inkscape:label="ns-usbloader">
|
||||
<path
|
||||
d="M 56.49804,17.188828 H 54.934697 L 50.217947,9.9065918 V 17.188828 H 49.082185 V 8.5169542 h 1.563342 l 4.716751,7.1619788 V 8.5169542 h 1.135762 z"
|
||||
style="font-size:13.3619px"
|
||||
id="path880" />
|
||||
<path
|
||||
d="m 64.488451,14.249209 v 0.62801 q 0,1.389637 -0.788353,1.924113 -0.788352,0.521115 -2.458589,0.521115 -1.068952,0 -2.645656,-0.213791 v -1.082314 q 1.576704,0.334048 2.725827,0.334048 0.921971,0 1.403,-0.200429 0.49439,-0.21379 0.49439,-0.8418 v -1.122399 q 0,-0.547838 -0.320686,-0.77499 -0.307323,-0.240515 -1.122399,-0.240515 H 60.76048 q -1.309466,0 -1.83058,-0.521114 -0.507752,-0.534476 -0.507752,-1.563342 v -0.694819 q 0,-1.0288662 0.721542,-1.5232565 0.734905,-0.4943903 2.685742,-0.4943903 0.935333,0 2.231438,0.1469809 v 0.9754187 q -1.483171,-0.2271523 -2.324971,-0.2271523 -1.242657,0 -1.656876,0.2538761 -0.400857,0.2405142 -0.400857,0.8284374 v 0.988781 q 0,0.454305 0.320686,0.668095 0.320686,0.200429 1.135762,0.200429 h 1.042228 q 1.349552,0 1.83058,0.49439 0.481029,0.481028 0.481029,1.536618 z"
|
||||
style="font-size:13.3619px"
|
||||
id="path882" />
|
||||
<path
|
||||
d="m 69.472442,13.848352 h -3.714608 v -0.962056 h 3.714608 z"
|
||||
style="font-size:13.3619px"
|
||||
id="path884" />
|
||||
<path
|
||||
d="m 77.903799,8.5169542 v 6.4537978 q 0,2.351695 -3.393923,2.351695 -0.681456,0 -1.215932,-0.09353 -0.534476,-0.08017 -1.055591,-0.307323 -0.521114,-0.240515 -0.815076,-0.734905 -0.293961,-0.49439 -0.293961,-1.215933 V 8.5169542 h 1.242656 V 14.95739 q 0,0.855162 0.574562,1.175847 0.574562,0.320686 1.590066,0.320686 1.015505,0 1.563343,-0.320686 0.561199,-0.320685 0.561199,-1.175847 V 8.5169542 Z"
|
||||
style="font-size:13.3619px"
|
||||
id="path886" />
|
||||
<path
|
||||
d="m 85.907587,14.249209 v 0.62801 q 0,1.389637 -0.788352,1.924113 -0.788353,0.521115 -2.45859,0.521115 -1.068952,0 -2.645656,-0.213791 v -1.082314 q 1.576704,0.334048 2.725827,0.334048 0.921971,0 1.403,-0.200429 0.49439,-0.21379 0.49439,-0.8418 v -1.122399 q 0,-0.547838 -0.320686,-0.77499 -0.307323,-0.240515 -1.122399,-0.240515 h -1.015505 q -1.309466,0 -1.83058,-0.521114 -0.507752,-0.534476 -0.507752,-1.563342 v -0.694819 q 0,-1.0288662 0.721542,-1.5232565 0.734905,-0.4943903 2.685742,-0.4943903 0.935333,0 2.231438,0.1469809 v 0.9754187 q -1.483171,-0.2271523 -2.324971,-0.2271523 -1.242657,0 -1.656875,0.2538761 -0.400857,0.2405142 -0.400857,0.8284374 v 0.988781 q 0,0.454305 0.320685,0.668095 0.320686,0.200429 1.135762,0.200429 h 1.042228 q 1.349552,0 1.83058,0.49439 0.481029,0.481028 0.481029,1.536618 z"
|
||||
style="font-size:13.3619px"
|
||||
id="path888" />
|
||||
<path
|
||||
d="m 94.031625,14.008695 v 1.456447 q 0,0.948695 -0.721543,1.33619 -0.721542,0.387496 -2.351694,0.387496 H 87.764894 V 8.5169542 h 3.099961 q 1.122399,0 1.750409,0.2271523 0.641371,0.2271523 0.828437,0.5611998 0.200429,0.3340475 0.200429,0.8551617 v 1.162485 q 0,0.534476 -0.307324,0.815076 -0.293962,0.2806 -0.881885,0.414219 v 0.05345 q 0.694819,0.120257 1.135761,0.481028 0.440943,0.360771 0.440943,0.921971 z m -1.603428,-2.725827 v -1.015505 q 0,-0.4943902 -0.360771,-0.6948187 -0.360772,-0.2004285 -1.202571,-0.2004285 h -1.803857 v 2.9396182 h 1.843942 q 0.828438,0 1.175848,-0.240514 0.347409,-0.253876 0.347409,-0.788352 z m 0.307324,4.128827 v -1.309466 q 0,-0.34741 -0.146981,-0.547838 -0.133619,-0.213791 -0.440943,-0.293962 -0.293962,-0.09353 -0.534476,-0.106895 -0.227152,-0.02672 -0.654733,-0.02672 h -1.89739 v 3.16677 h 1.89739 q 0.975419,0 1.376276,-0.200428 0.400857,-0.200429 0.400857,-0.681457 z"
|
||||
style="font-size:13.3619px"
|
||||
id="path890" />
|
||||
<path
|
||||
d="M 97.07815,17.188828 H 95.875579 V 7.8354973 h 1.202571 z"
|
||||
style="font-size:13.3619px"
|
||||
id="path892" />
|
||||
<path
|
||||
d="m 104.8815,12.899658 v 2.244799 q 0,0.601285 -0.14698,1.015504 -0.14698,0.414219 -0.37413,0.641371 -0.22715,0.227153 -0.65474,0.34741 -0.41421,0.120257 -0.80171,0.146981 -0.37413,0.02672 -1.00214,0.02672 -0.80172,0 -1.25602,-0.05345 -0.44094,-0.05345 -0.895248,-0.253876 -0.440942,-0.213791 -0.641371,-0.668095 -0.187067,-0.454305 -0.187067,-1.202571 v -2.244799 q 0,-0.641372 0.146981,-1.082314 0.160343,-0.440943 0.374134,-0.681457 0.227152,-0.240515 0.654731,-0.360772 0.42758,-0.133619 0.78835,-0.160342 0.37414,-0.02672 1.01551,-0.02672 0.64137,0 1.00214,0.02672 0.37413,0.02672 0.80171,0.160342 0.42759,0.120257 0.64138,0.360772 0.22715,0.240514 0.37413,0.681457 0.16034,0.440942 0.16034,1.082314 z m -1.22929,2.418503 v -2.618932 q 0,-0.895247 -0.36077,-1.109038 -0.36078,-0.21379 -1.38964,-0.21379 -1.02887,0 -1.38964,0.21379 -0.36077,0.213791 -0.36077,1.109038 v 2.618932 q 0,0.427581 0.0935,0.681457 0.0935,0.253876 0.34741,0.374134 0.25388,0.106895 0.52112,0.133619 0.26723,0.02672 0.78835,0.02672 0.52111,0 0.78835,-0.02672 0.26724,-0.02672 0.52111,-0.133619 0.25388,-0.120258 0.34741,-0.374134 0.0935,-0.253876 0.0935,-0.681457 z"
|
||||
style="font-size:13.3619px"
|
||||
id="path894" />
|
||||
<path
|
||||
d="m 111.85643,17.188828 h -1.16249 V 16.57418 q -0.14698,0.748267 -1.95084,0.748267 -1.33619,0 -1.8573,-0.400857 -0.50775,-0.414219 -0.50775,-1.656876 0,-1.082314 0.48103,-1.483171 0.48103,-0.414219 1.8573,-0.414219 h 1.93748 v -1.028866 q 0,-0.534476 -0.33405,-0.721543 -0.32069,-0.187067 -1.2293,-0.187067 -0.98878,0 -2.21807,0.160343 v -0.881885 q 1.32283,-0.120257 2.39178,-0.120257 1.63015,0 2.11118,0.400857 0.48103,0.387495 0.48103,1.630152 z m -1.20257,-1.309467 V 14.11559 h -1.85731 q -0.82844,0 -1.04223,0.213791 -0.20042,0.21379 -0.20042,0.975419 0,0.681456 0.21379,0.962056 0.22715,0.267238 0.93533,0.267238 h 0.24051 q 0.34741,0 0.57456,-0.01336 0.24052,-0.01336 0.53448,-0.06681 0.29396,-0.06681 0.44094,-0.200429 0.16035,-0.14698 0.16035,-0.374134 z"
|
||||
style="font-size:13.3619px"
|
||||
id="path896" />
|
||||
<path
|
||||
d="m 119.59297,17.188828 h -1.17585 v -0.761629 q 0,0.34741 -0.58792,0.62801 -0.57456,0.267238 -1.5767,0.267238 -1.403,0 -1.97757,-0.440943 -0.57456,-0.440943 -0.57456,-1.61679 v -2.846085 q 0,-0.975419 0.60129,-1.402999 0.60128,-0.427581 2.01765,-0.427581 0.76162,0 1.40299,0.200428 0.65474,0.200429 0.6681,0.62801 h 0.0267 q -0.0267,-1.095676 -0.0267,-1.6435142 V 7.8354973 h 1.20257 z m -1.20257,-1.696962 v -3.193494 q 0,-0.868524 -1.77713,-0.868524 -1.06895,0 -1.403,0.160343 -0.32069,0.160343 -0.32069,0.708181 v 3.193494 q 0,0.547838 0.36077,0.77499 0.37414,0.227153 1.25602,0.227153 0.98878,0 1.42973,-0.227153 0.4543,-0.227152 0.4543,-0.77499 z"
|
||||
style="font-size:13.3619px"
|
||||
id="path898" />
|
||||
<path
|
||||
d="m 126.88855,14.222486 h -4.34261 v 0.975418 q 0,0.681457 0.48103,0.975419 0.48102,0.2806 1.42972,0.2806 0.92197,0 2.17799,-0.320686 v 0.921972 q -1.20257,0.267238 -2.33833,0.267238 -2.96635,0 -2.96635,-1.977562 v -2.552123 q 0,-1.189209 0.68146,-1.696961 0.68146,-0.507752 2.17799,-0.507752 1.403,0 2.04437,0.49439 0.65473,0.481028 0.65473,1.710323 z m -1.20257,-0.788352 v -1.015505 q 0,-0.587924 -0.36077,-0.801714 -0.36077,-0.227152 -1.20257,-0.227152 -0.80171,0 -1.18921,0.21379 -0.38749,0.213791 -0.38749,0.815076 v 1.015505 z"
|
||||
style="font-size:13.3619px"
|
||||
id="path900" />
|
||||
<path
|
||||
d="m 132.20659,11.616915 h -0.6681 q -0.82844,0 -1.22929,0.21379 -0.3875,0.213791 -0.3875,0.801715 v 4.556408 h -1.20257 v -6.46716 h 1.13576 v 1.05559 q 0,-0.467667 0.57456,-0.828438 0.58793,-0.360771 1.18921,-0.360771 h 0.58793 z"
|
||||
style="font-size:13.3619px"
|
||||
id="path902" />
|
||||
</g>
|
||||
transform="scale(0.97866107,1.0218042)"
|
||||
inkscape:label="ns-usbloader"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan980"
|
||||
x="47.959785"
|
||||
y="17.188828"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13.3619px;font-family:Play;-inkscape-font-specification:'Play, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;stroke-width:0.357908">NS-USBloader</tspan></text>
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:0.264583"
|
||||
d="m 21.967046,0 c -0.0065,-1.9994448e-6 -0.01188,0.0054 -0.01188,0.01188 v 44.976581 c 0,0.0065 0.0054,0.01188 0.01188,0.01188 h 2.000395 c 0.0065,0 0.01188,-0.0054 0.01188,-0.01188 V 0.011885 c 0,-0.0065 -0.0054,-0.011879999445 -0.01188,-0.011879999445 z"
|
||||
id="rect1136"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csssssssc" />
|
||||
<g
|
||||
inkscape:label="CREATIVE_COMMONS_SHIELD"
|
||||
transform="matrix(0.1713381,0,0,0.17131892,77.526533,36.479842)"
|
||||
id="g287"
|
||||
inkscape:export-filename="/mnt/hgfs/Bov/Documents/Work/2007/cc/identity/srr buttons/big/by-sa.png"
|
||||
inkscape:export-xdpi="300.23013"
|
||||
inkscape:export-ydpi="300.23013">
|
||||
<path
|
||||
id="path3817_2_"
|
||||
nodetypes="ccccccc"
|
||||
d="m 182.23532,75.39014 114.06396,0.20312 c 1.59375,0 3.01758,-0.23682 3.01758,3.18018 l -0.13965,37.56689 H 179.3569 V 78.63379 c 0,-1.68457 0.16309,-3.24365 2.87842,-3.24365 z"
|
||||
style="fill:#aab2ab" />
|
||||
<g
|
||||
id="g5908_2_"
|
||||
transform="matrix(0.872921,0,0,0.872921,50.12536,143.2144)">
|
||||
<path
|
||||
id="path5906_2_"
|
||||
cx="296.35416"
|
||||
ry="22.939548"
|
||||
cy="264.3577"
|
||||
type="arc"
|
||||
rx="22.939548"
|
||||
d="m 187.20944,-55.6792 c 0.006,8.68024 -7.02786,15.72095 -15.7081,15.72708 -8.68021,0.005 -15.72205,-7.02786 -15.72708,-15.70804 0,-0.0067 0,-0.01233 0,-0.01904 -0.005,-8.68134 7.02783,-15.72205 15.70807,-15.72711 8.68134,-0.0056 15.72208,7.02789 15.72711,15.70807 0,0.0056 0,0.01233 0,0.01904 z"
|
||||
style="fill:#ffffff" />
|
||||
<g
|
||||
id="g5706_2_"
|
||||
transform="translate(-289.6157,99.0653)">
|
||||
<path
|
||||
id="path5708_2_"
|
||||
d="m 473.88455,-167.54724 c 3.48541,3.48596 5.22839,7.75391 5.22839,12.80273 0,5.04938 -1.7128,9.27148 -5.13834,12.66736 -3.63531,3.5766 -7.93179,5.36432 -12.88947,5.36432 -4.89777,0 -9.11987,-1.77261 -12.6651,-5.31955 -3.54584,-3.54581 -5.31845,-7.78299 -5.31845,-12.71213 0,-4.92859 1.77261,-9.19598 5.31845,-12.80273 3.4552,-3.48651 7.67725,-5.22894 12.6651,-5.22894 5.04829,0 9.31401,1.74243 12.79942,5.22894 z m -23.11798,2.34485 c -2.94675,2.97638 -4.41956,6.46289 -4.41956,10.46234 0,3.99835 1.45828,7.4552 4.37424,10.37067 2.91653,2.9165 6.38849,4.37476 10.41705,4.37476 4.02853,0 7.53018,-1.47281 10.50656,-4.41901 2.8259,-2.73584 4.23941,-6.17706 4.23941,-10.32642 0,-4.11804 -1.43646,-7.61292 -4.30768,-10.48474 -2.87064,-2.87067 -6.34988,-4.30652 -10.43829,-4.30652 -4.08837,0 -7.54638,1.44318 -10.37173,4.32892 z m 7.75449,8.70312 c -0.45032,-0.98163 -1.12433,-1.47223 -2.02325,-1.47223 -1.58914,0 -2.38342,1.06952 -2.38342,3.2085 0,2.13959 0.79428,3.20911 2.38342,3.20911 1.04938,0 1.79895,-0.5213 2.24866,-1.56512 l 2.20276,1.17303 c -1.04993,1.86548 -2.62506,2.79901 -4.72549,2.79901 -1.6199,0 -2.91763,-0.4967 -3.89206,-1.48956 -0.97607,-0.99341 -1.46274,-2.36273 -1.46274,-4.10797 0,-1.71558 0.50229,-3.07709 1.50748,-4.08563 1.00519,-1.00793 2.25705,-1.51251 3.75781,-1.51251 2.22012,0 3.80984,0.87488 4.77081,2.62286 z m 10.36334,0 c -0.45087,-0.98163 -1.11148,-1.47223 -1.98239,-1.47223 -1.62106,0 -2.43213,1.06952 -2.43213,3.2085 0,2.13959 0.81107,3.20911 2.43213,3.20911 1.05103,0 1.78717,-0.5213 2.20724,-1.56512 l 2.25201,1.17303 c -1.04825,1.86548 -2.62119,2.79901 -4.71768,2.79901 -1.61771,0 -2.91263,-0.4967 -3.88647,-1.48956 -0.97217,-0.99341 -1.45938,-2.36273 -1.45938,-4.10797 0,-1.71558 0.49448,-3.07709 1.48288,-4.08563 0.98782,-1.00793 2.24527,-1.51251 3.77347,-1.51251 2.21619,0 3.80368,0.87488 4.76132,2.62286 z" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
d="M 297.29639,74.91064 H 181.06688 c -1.24658,0 -2.26074,1.01465 -2.26074,2.26123 v 39.49561 c 0,0.28174 0.22852,0.51074 0.51025,0.51074 h 119.73 c 0.28174,0 0.51074,-0.229 0.51074,-0.51074 v -39.4956 c 0,-1.24659 -1.01416,-2.26124 -2.26074,-2.26124 z m -116.22951,1.02149 h 116.22951 c 0.68359,0 1.23926,0.55615 1.23926,1.23975 0,0 0,15.91943 0,27.41846 H 215.4619 c -3.04492,5.50537 -8.91113,9.24365 -15.64355,9.24365 -6.73535,0 -12.6001,-3.73486 -15.64355,-9.24365 h -4.34814 c 0,-11.49902 0,-27.41846 0,-27.41846 -2e-5,-0.6836 0.55663,-1.23975 1.24022,-1.23975 z"
|
||||
id="path294" />
|
||||
<g
|
||||
enable-background="new "
|
||||
id="g296">
|
||||
<path
|
||||
d="m 265.60986,112.8833 c 0.0801,0.15576 0.1875,0.28174 0.32129,0.37842 0.13379,0.0962 0.29004,0.16797 0.46973,0.21436 0.18066,0.0469 0.36719,0.0703 0.55957,0.0703 0.12988,0 0.26953,-0.0107 0.41895,-0.0327 0.14844,-0.0215 0.28809,-0.064 0.41895,-0.12598 0.12988,-0.062 0.23926,-0.14795 0.3252,-0.25684 0.0879,-0.10889 0.13086,-0.24707 0.13086,-0.41553 0,-0.18018 -0.0576,-0.32617 -0.17285,-0.43848 -0.11426,-0.1123 -0.26562,-0.20508 -0.45215,-0.28027 -0.18555,-0.0742 -0.39746,-0.13965 -0.63281,-0.1958 -0.23633,-0.0562 -0.47559,-0.11816 -0.71777,-0.18701 -0.24902,-0.062 -0.49121,-0.13818 -0.72754,-0.22852 -0.23535,-0.0898 -0.44727,-0.20703 -0.63379,-0.3501 -0.18652,-0.14307 -0.33691,-0.32178 -0.45215,-0.53662 -0.11426,-0.21484 -0.17188,-0.47461 -0.17188,-0.7793 0,-0.34277 0.0732,-0.63965 0.21875,-0.8916 0.14648,-0.25195 0.33789,-0.46191 0.57422,-0.63037 0.23535,-0.16797 0.50293,-0.29248 0.80176,-0.37354 0.29785,-0.0806 0.59668,-0.12109 0.89453,-0.12109 0.34863,0 0.68262,0.0391 1.00293,0.11719 0.31934,0.0776 0.60449,0.2041 0.85254,0.37842 0.24902,0.17432 0.44629,0.39697 0.59277,0.66797 0.14551,0.271 0.21875,0.59961 0.21875,0.98535 h -1.42188 c -0.0127,-0.19922 -0.0547,-0.36426 -0.125,-0.49463 -0.0713,-0.13086 -0.16602,-0.2334 -0.2832,-0.30859 -0.11816,-0.0742 -0.25293,-0.12744 -0.4043,-0.1582 -0.15234,-0.0312 -0.31738,-0.0469 -0.49707,-0.0469 -0.11719,0 -0.23535,0.0127 -0.35254,0.0371 -0.11816,0.0254 -0.22461,0.0688 -0.32031,0.13086 -0.0967,0.0625 -0.17578,0.14014 -0.2373,0.2334 -0.0615,0.0937 -0.0928,0.21191 -0.0928,0.35498 0,0.13086 0.0244,0.23682 0.0742,0.31738 0.0498,0.0811 0.14844,0.15576 0.29395,0.22412 0.14551,0.0684 0.34766,0.13721 0.60547,0.20557 0.25781,0.0684 0.59473,0.15576 1.01172,0.26123 0.12402,0.0249 0.2959,0.0703 0.5166,0.13574 0.2207,0.0654 0.43945,0.16943 0.65723,0.3125 0.21777,0.14355 0.40527,0.33496 0.56445,0.57422 0.1582,0.23975 0.2373,0.54639 0.2373,0.91992 0,0.30518 -0.0596,0.58838 -0.17773,0.84961 -0.11816,0.26172 -0.29395,0.4873 -0.52734,0.67676 -0.2334,0.19043 -0.52246,0.33789 -0.86719,0.44385 -0.3457,0.10596 -0.74609,0.15869 -1.19922,0.15869 -0.36719,0 -0.72363,-0.0454 -1.06934,-0.13574 -0.34473,-0.0903 -0.65039,-0.23242 -0.91504,-0.42578 -0.26367,-0.19336 -0.47363,-0.43994 -0.62988,-0.73877 -0.15527,-0.29932 -0.22949,-0.65381 -0.22363,-1.06494 h 1.42188 c -3e-5,0.22412 0.04,0.41406 0.12106,0.56933 z"
|
||||
id="path298"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
d="m 273.8667,107.8667 2.49316,6.66406 h -1.52246 l -0.50391,-1.48438 h -2.49316 l -0.52246,1.48438 h -1.47461 l 2.52051,-6.66406 z m 0.084,4.08594 -0.83984,-2.44336 h -0.0186 l -0.86914,2.44336 z"
|
||||
id="path300"
|
||||
style="fill:#ffffff" />
|
||||
</g>
|
||||
<g
|
||||
enable-background="new "
|
||||
id="g302">
|
||||
<path
|
||||
d="m 239.17821,107.8667 c 0.31738,0 0.60742,0.0283 0.86914,0.084 0.26172,0.0561 0.48633,0.14795 0.67383,0.27539 0.18652,0.12744 0.33203,0.29688 0.43457,0.5083 0.10254,0.21142 0.1543,0.47266 0.1543,0.78369 0,0.33594 -0.0762,0.61523 -0.22949,0.83936 -0.15234,0.22412 -0.37891,0.40723 -0.67773,0.55029 0.41211,0.11816 0.71973,0.3252 0.92285,0.62109 0.20312,0.29589 0.30469,0.65234 0.30469,1.06934 0,0.33594 -0.0654,0.62695 -0.19629,0.87305 -0.13086,0.24561 -0.30762,0.44629 -0.52832,0.60205 -0.22168,0.15576 -0.47461,0.271 -0.75781,0.34521 -0.28418,0.0752 -0.5752,0.1123 -0.875,0.1123 h -3.23633 v -6.66406 h 3.14159 z m -0.1875,2.69531 c 0.26172,0 0.47656,-0.062 0.64551,-0.18604 0.16797,-0.12451 0.25195,-0.32568 0.25195,-0.60498 0,-0.15527 -0.0283,-0.28271 -0.084,-0.38184 -0.0566,-0.0996 -0.13086,-0.17676 -0.22461,-0.23291 -0.0937,-0.0557 -0.20117,-0.0947 -0.32227,-0.11621 -0.12207,-0.022 -0.24805,-0.0327 -0.37891,-0.0327 h -1.37305 v 1.55469 z m 0.0859,2.82813 c 0.14355,0 0.28027,-0.0137 0.41113,-0.042 0.13086,-0.0278 0.24707,-0.0747 0.34668,-0.13965 0.0996,-0.0654 0.17871,-0.1543 0.23828,-0.26611 0.0596,-0.11181 0.0889,-0.25488 0.0889,-0.4292 0,-0.3418 -0.0967,-0.58594 -0.29004,-0.73193 -0.19336,-0.14599 -0.44922,-0.21924 -0.7666,-0.21924 h -1.59961 v 1.82812 z"
|
||||
id="path304"
|
||||
style="fill:#ffffff" />
|
||||
<path
|
||||
d="m 241.88914,107.8667 h 1.64355 l 1.56055,2.63184 1.55078,-2.63184 h 1.63379 l -2.47363,4.10645 v 2.55762 h -1.46875 v -2.59473 z"
|
||||
id="path306"
|
||||
style="fill:#ffffff" />
|
||||
</g>
|
||||
<g
|
||||
id="g6316_1_"
|
||||
transform="matrix(0.624995,0,0,0.624995,391.2294,176.9332)">
|
||||
<path
|
||||
id="path6318_1_"
|
||||
cx="475.97119"
|
||||
ry="29.209877"
|
||||
cy="252.08646"
|
||||
type="arc"
|
||||
rx="29.209877"
|
||||
d="m -175.0083,-139.1153 c 0.006,9.4118 -7.61725,17.04779 -17.02982,17.05481 -9.41101,0.007 -17.047,-7.61725 -17.05481,-17.02979 0,-0.008 0,-0.0172 0,-0.025 -0.006,-9.41254 7.6188,-17.047 17.02982,-17.05481 9.41257,-0.007 17.04855,7.61804 17.05481,17.02985 0,0.009 0,0.0164 0,0.025 z"
|
||||
style="fill:#ffffff" />
|
||||
<g
|
||||
id="g6320_1_"
|
||||
transform="translate(-23.9521,-89.72962)">
|
||||
<path
|
||||
id="path6322_1_"
|
||||
d="m -168.2204,-68.05536 c -5.17194,0 -9.54852,1.80469 -13.13135,5.41333 -3.67661,3.73444 -5.51413,8.1532 -5.51413,13.25635 0,5.10315 1.83752,9.49152 5.51413,13.1626 3.67502,3.67194 8.05316,5.50787 13.13135,5.50787 5.14066,0 9.59537,-1.85156 13.36728,-5.55475 3.55005,-3.51562 5.3266,-7.88831 5.3266,-13.11572 0,-5.22662 -1.8078,-9.64697 -5.42191,-13.25635 -3.61407,-3.60864 -8.03756,-5.41333 -13.27197,-5.41333 z m 0.0469,3.36017 c 4.23752,0 7.836,1.49298 10.79697,4.48053 2.98907,2.9563 4.48441,6.56567 4.48441,10.82898 0,4.29382 -1.46252,7.85712 -4.39224,10.68915 -3.08438,3.04926 -6.71411,4.57349 -10.88913,4.57349 -4.17505,0 -7.7735,-1.5094 -10.79541,-4.52661 -3.02188,-3.01953 -4.53284,-6.59692 -4.53284,-10.73602 0,-4.13831 1.52658,-7.74847 4.57971,-10.82898 2.92815,-2.98756 6.51098,-4.48054 10.74853,-4.48054 z" />
|
||||
<path
|
||||
id="path6324_1_"
|
||||
d="m -176.49548,-52.02087 c 0.74377,-4.69769 4.05161,-7.20862 8.1954,-7.20862 5.96097,0 9.59225,4.32501 9.59225,10.09229 0,5.62738 -3.86411,9.99927 -9.686,9.99927 -4.00473,0 -7.58914,-2.46484 -8.24228,-7.30084 h 4.70319 c 0.14062,2.51099 1.77032,3.39459 4.09845,3.39459 2.65317,0 4.37817,-2.4649 4.37817,-6.23291 0,-3.95233 -1.49063,-6.04535 -4.28598,-6.04535 -2.04846,0 -3.8172,0.74457 -4.19064,3.30157 l 1.36874,-0.007 -3.70316,3.7016 -3.7016,-3.7016 z" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g313">
|
||||
<circle
|
||||
cx="242.56226"
|
||||
cy="90.224609"
|
||||
r="10.8064"
|
||||
id="circle315"
|
||||
style="fill:#ffffff" />
|
||||
<g
|
||||
id="g317">
|
||||
<path
|
||||
d="m 245.68994,87.09766 c 0,-0.4165 -0.33789,-0.75342 -0.75391,-0.75342 h -4.77246 c -0.41602,0 -0.75391,0.33691 -0.75391,0.75342 v 4.77295 h 1.33105 v 5.65234 h 3.61719 v -5.65234 h 1.33203 v -4.77295 z"
|
||||
id="path319" />
|
||||
<circle
|
||||
cx="242.5498"
|
||||
cy="84.083008"
|
||||
r="1.63232"
|
||||
id="circle321" />
|
||||
</g>
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="m 242.53467,78.31836 c -3.23145,0 -5.96826,1.12744 -8.20752,3.38379 -2.29785,2.33301 -3.44629,5.09521 -3.44629,8.28418 0,3.18897 1.14844,5.93213 3.44629,8.22705 2.29785,2.29443 5.03418,3.44189 8.20752,3.44189 3.21289,0 5.99805,-1.15674 8.35352,-3.47168 2.2207,-2.19678 3.33008,-4.92969 3.33008,-8.19727 0,-3.26758 -1.12891,-6.02881 -3.3877,-8.28418 -2.25879,-2.25634 -5.02442,-3.38378 -8.2959,-3.38378 z m 0.0293,2.09961 c 2.64844,0 4.89746,0.93359 6.74707,2.80078 1.87012,1.84717 2.80469,4.10352 2.80469,6.76758 0,2.68359 -0.91504,4.91113 -2.74609,6.68066 -1.92773,1.90576 -4.19629,2.8584 -6.80566,2.8584 -2.60937,0 -4.8584,-0.94287 -6.74658,-2.82959 -1.88965,-1.88623 -2.8335,-4.12256 -2.8335,-6.70947 0,-2.58643 0.9541,-4.84229 2.8623,-6.76758 1.83057,-1.86719 4.07031,-2.80078 6.71777,-2.80078 z"
|
||||
id="path323"
|
||||
style="fill-rule:evenodd" />
|
||||
</g>
|
||||
</g>
|
||||
<text
|
||||
inkscape:label="HeyMomLookAtMe"
|
||||
inkscape:transform-center-y="-0.1984375"
|
||||
inkscape:transform-center-x="-0.33072917"
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:2.82222px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583"
|
||||
x="108.57767"
|
||||
y="48.318489"
|
||||
id="text921"><tspan
|
||||
sodipodi:role="line"
|
||||
x="108.57767"
|
||||
y="48.318489"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:2.82222px;font-family:'Nunito Sans';-inkscape-font-specification:'Nunito Sans Bold';stroke-width:0.264583"
|
||||
id="tspan923">Dmitry Isaenko</tspan></text>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 38 KiB |
|
@ -18,8 +18,6 @@
|
|||
*/
|
||||
package nsusbloader;
|
||||
|
||||
import javafx.scene.text.Font;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
|
@ -29,26 +27,22 @@ public class AppPreferences {
|
|||
|
||||
private final Preferences preferences;
|
||||
private final Locale locale;
|
||||
public static final String[] GOLDLEAF_SUPPORTED_VERSIONS = {"v0.5", "v0.7.x", "v0.8-0.9", "v0.10+"};
|
||||
private static final Font DEFAULT_FONT = Font.getDefault();
|
||||
public static final String[] goldleafSupportedVersions = {"v0.5", "v0.7.x", "v0.8-0.9", "v0.10"};
|
||||
|
||||
private AppPreferences(){
|
||||
this.preferences = Preferences.userRoot().node("NS-USBloader");
|
||||
String localeCode = preferences.get("locale", Locale.getDefault().toString());
|
||||
if (localeCode.length() < 5)
|
||||
this.locale = new Locale("en", "EN");
|
||||
else
|
||||
this.locale = new Locale(localeCode.substring(0, 2), localeCode.substring(3));
|
||||
this.locale = new Locale(localeCode.substring(0, 2), localeCode.substring(3, 5));
|
||||
}
|
||||
|
||||
public String getTheme(){
|
||||
String theme = preferences.get("THEME", "/res/app_dark.css"); // Don't let user change settings manually
|
||||
String theme = preferences.get("THEME", "/res/app_dark.css"); // Don't let user to change settings manually
|
||||
if (!theme.matches("(^/res/app_dark.css$)|(^/res/app_light.css$)"))
|
||||
theme = "/res/app_dark.css";
|
||||
return theme;
|
||||
}
|
||||
public int getProtocol(){
|
||||
int protocolIndex = preferences.getInt("protocol_index", 0); // Don't let user change settings manually
|
||||
int protocolIndex = preferences.getInt("protocol_index", 0); // Don't let user to change settings manually
|
||||
if (protocolIndex < 0 || protocolIndex > 1)
|
||||
protocolIndex = 0;
|
||||
return protocolIndex;
|
||||
|
@ -56,7 +50,7 @@ public class AppPreferences {
|
|||
public void setProtocol(int protocolIndex){ preferences.putInt("protocol_index", protocolIndex); }
|
||||
|
||||
public String getNetUsb(){
|
||||
String netUsb = preferences.get("NETUSB", "USB"); // Don't let user change settings manually
|
||||
String netUsb = preferences.get("NETUSB", "USB"); // Don't let user to change settings manually
|
||||
if (!netUsb.matches("(^USB$)|(^NET$)"))
|
||||
netUsb = "USB";
|
||||
return netUsb;
|
||||
|
@ -120,7 +114,7 @@ public class AppPreferences {
|
|||
public void setNspFileFilterGL(boolean prop){preferences.putBoolean("GL_NSP_FILTER", prop);}
|
||||
|
||||
public int getGlVersion(){
|
||||
return preferences.getInt("gl_ver", GOLDLEAF_SUPPORTED_VERSIONS.length - 1);
|
||||
return preferences.getInt("gl_ver", goldleafSupportedVersions.length - 1);
|
||||
}
|
||||
public void setGlVersion(int version){ preferences.putInt("gl_ver", version);}
|
||||
|
||||
|
@ -144,28 +138,4 @@ public class AppPreferences {
|
|||
|
||||
public String getLastOpenedTab(){ return preferences.get("recent_tab", ""); }
|
||||
public void setLastOpenedTab(String tabId){ preferences.put("recent_tab", tabId); }
|
||||
// Patches
|
||||
public String getKeysLocation(){ return preferences.get("keys", ""); }
|
||||
public void setKeysLocation(String path){ preferences.put("keys", path); }
|
||||
|
||||
public String getPatchesSaveToLocation(){ return FilesHelper.getRealFolder(preferences.get("patches_saveto", System.getProperty("user.home"))); }
|
||||
public void setPatchesSaveToLocation(String value){ preferences.put("patches_saveto", value); }
|
||||
|
||||
public boolean getPatchesTabInvisible(){return preferences.getBoolean("patches_tab_visible", true); }
|
||||
public void setPatchesTabInvisible(boolean value){preferences.putBoolean("patches_tab_visible", value);}
|
||||
public String getPatchPattern(String type, int moduleNumber, int offsetId){ return preferences.get(String.format("%s_%02x_%02x", type, moduleNumber, offsetId), ""); }
|
||||
public void setPatchPattern(String fullTypeSpecifier, String offset){ preferences.put(fullTypeSpecifier, offset); }
|
||||
|
||||
public String getFontFamily(){ return preferences.get("font_family", DEFAULT_FONT.getFamily()); }
|
||||
public double getFontSize(){ return preferences.getDouble("font_size", DEFAULT_FONT.getSize()); }
|
||||
public String getFontStyle(){
|
||||
final String fontFamily = preferences.get("font_family", DEFAULT_FONT.getFamily());
|
||||
final double fontSize = preferences.getDouble("font_size", DEFAULT_FONT.getSize());
|
||||
|
||||
return String.format("-fx-font-family: \"%s\"; -fx-font-size: %.0f;", fontFamily, fontSize);
|
||||
}
|
||||
public void setFontStyle(String fontFamily, double size){
|
||||
preferences.put("font_family", fontFamily);
|
||||
preferences.putDouble("font_size", size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -39,13 +39,10 @@ import java.util.ResourceBundle;
|
|||
|
||||
public class FilesDropHandle {
|
||||
|
||||
public FilesDropHandle(List<File> files,
|
||||
String filesRegex,
|
||||
String foldersRegex,
|
||||
NSTableViewController tableController){
|
||||
public FilesDropHandle(List<File> files, String filesRegex, String foldersRegex){
|
||||
FilesDropHandleTask filesDropHandleTask = new FilesDropHandleTask(files, filesRegex, foldersRegex);
|
||||
|
||||
ResourceBundle resourceBundle = MediatorControl.INSTANCE.getResourceBundle();
|
||||
ResourceBundle resourceBundle = MediatorControl.getInstance().getResourceBundle();
|
||||
Button cancelButton = new Button(resourceBundle.getString("btn_Cancel"));
|
||||
|
||||
ProgressIndicator progressIndicator = new ProgressIndicator();
|
||||
|
@ -90,7 +87,6 @@ public class FilesDropHandle {
|
|||
Scene mainScene = new Scene(parentVBox, 310, 185);
|
||||
|
||||
mainScene.getStylesheets().add(AppPreferences.getInstance().getTheme());
|
||||
parentVBox.setStyle(AppPreferences.getInstance().getFontStyle());
|
||||
|
||||
stage.setOnHidden(windowEvent -> filesDropHandleTask.cancel(true ) );
|
||||
|
||||
|
@ -104,7 +100,7 @@ public class FilesDropHandle {
|
|||
List<File> allFiles = filesDropHandleTask.getValue();
|
||||
|
||||
if (! allFiles.isEmpty()) {
|
||||
tableController.setFiles(allFiles);
|
||||
MediatorControl.getInstance().getGamesController().tableFilesListController.setFiles(allFiles);
|
||||
}
|
||||
stage.close();
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -32,7 +32,7 @@ public class FilesDropHandleTask extends Task<List<File>> {
|
|||
private final List<File> filesDropped;
|
||||
private final List<File> allFiles;
|
||||
|
||||
private final String messageTemplate;
|
||||
private String messageTemplate;
|
||||
private long filesScanned = 0;
|
||||
private long filesAdded = 0;
|
||||
|
||||
|
@ -43,12 +43,12 @@ public class FilesDropHandleTask extends Task<List<File>> {
|
|||
this.filesRegex = filesRegex;
|
||||
this.foldersRegex = foldersRegex;
|
||||
this.allFiles = new ArrayList<>();
|
||||
this.messageTemplate = MediatorControl.INSTANCE.getResourceBundle().getString("windowBodyFilesScanned");
|
||||
this.messageTemplate = MediatorControl.getInstance().getResourceBundle().getString("windowBodyFilesScanned");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<File> call() {
|
||||
if (filesDropped == null || filesDropped.isEmpty())
|
||||
if (filesDropped == null || filesDropped.size() == 0)
|
||||
return allFiles;
|
||||
|
||||
for (File file : filesDropped){
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
Copyright 2019-2023 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Controllers;
|
||||
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.stage.Stage;
|
||||
import nsusbloader.AppPreferences;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class FontSettings {
|
||||
public FontSettings(ResourceBundle resourceBundle) throws Exception{
|
||||
Stage stage = new Stage();
|
||||
stage.setMinWidth(650);
|
||||
stage.setMinHeight(450);
|
||||
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/FontSettings.fxml"));
|
||||
fxmlLoader.setResources(resourceBundle);
|
||||
|
||||
stage.setTitle(resourceBundle.getString("tab2_Btn_ApplicationFont"));
|
||||
stage.getIcons().addAll(
|
||||
new Image("/res/app_icon32x32.png"),
|
||||
new Image("/res/app_icon48x48.png"),
|
||||
new Image("/res/app_icon64x64.png"),
|
||||
new Image("/res/app_icon128x128.png"));
|
||||
|
||||
Parent parent = fxmlLoader.load();
|
||||
Scene fontScene = new Scene(parent, 660, 525);
|
||||
|
||||
fontScene.getStylesheets().add(AppPreferences.getInstance().getTheme());
|
||||
parent.setStyle(AppPreferences.getInstance().getFontStyle());
|
||||
|
||||
stage.setAlwaysOnTop(true);
|
||||
stage.setScene(fontScene);
|
||||
stage.show();
|
||||
}
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Controllers;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.stage.Stage;
|
||||
import nsusbloader.AppPreferences;
|
||||
import nsusbloader.MediatorControl;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class FontSettingsController implements Initializable {
|
||||
private final AppPreferences preferences = AppPreferences.getInstance();
|
||||
|
||||
@FXML
|
||||
private Button applyBtn, cancelBtn, resetBtn;
|
||||
|
||||
@FXML
|
||||
private ListView<String> fontsLv;
|
||||
|
||||
@FXML
|
||||
private Spinner<Double> fontSizeSpinner;
|
||||
|
||||
@FXML
|
||||
private Text exampleText;
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
applyBtn.setDefaultButton(true);
|
||||
applyBtn.getStyleClass().add("buttonUp");
|
||||
applyBtn.setOnAction(e -> applyChanges());
|
||||
|
||||
cancelBtn.setCancelButton(true);
|
||||
cancelBtn.setOnAction(e -> closeWindow());
|
||||
|
||||
resetBtn.setOnAction(e -> reset());
|
||||
|
||||
fontsLv.setCellFactory(item -> getCellFactory());
|
||||
fontsLv.setItems(getFonts());
|
||||
fontsLv.getSelectionModel().select(preferences.getFontFamily());
|
||||
fontsLv.getSelectionModel().selectedIndexProperty().addListener(
|
||||
(observableValue, oldValueNumber, newValueNumber) -> setExampleTextFont());
|
||||
fontsLv.setFixedCellSize(40.0);
|
||||
|
||||
fontSizeSpinner.setEditable(false);
|
||||
fontSizeSpinner.setValueFactory(getValueFactory());
|
||||
|
||||
exampleText.setText(resourceBundle.getString("fontPreviewText"));
|
||||
|
||||
fontSizeSpinner.getValueFactory().setValue(preferences.getFontSize());
|
||||
}
|
||||
|
||||
private ListCell<String> getCellFactory(){
|
||||
return new ListCell<>(){
|
||||
@Override
|
||||
protected void updateItem(String item, boolean empty) {
|
||||
super.updateItem(item, empty);
|
||||
if (empty || item == null)
|
||||
return;
|
||||
Font font = Font.font(item);
|
||||
Text itemText = new Text(item);
|
||||
itemText.setFont(font);
|
||||
setGraphic(itemText);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private ObservableList<String> getFonts(){
|
||||
ObservableList<String> fonts = FXCollections.observableArrayList();
|
||||
fonts.addAll(Font.getFamilies());
|
||||
|
||||
return fonts;
|
||||
}
|
||||
|
||||
private SpinnerValueFactory<Double> getValueFactory(){
|
||||
return new SpinnerValueFactory<>() {
|
||||
@Override
|
||||
public void decrement(int i) {
|
||||
double value = getValue() - i;
|
||||
if (value < 4)
|
||||
return;
|
||||
|
||||
setValue(value);
|
||||
setExampleTextFont(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increment(int i) {
|
||||
double value = getValue() + i;
|
||||
if (value > 100)
|
||||
return;
|
||||
|
||||
setValue(value);
|
||||
setExampleTextFont(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void setExampleTextFont(){
|
||||
setExampleTextFont(fontsLv.getSelectionModel().getSelectedItem(), fontSizeSpinner.getValue());
|
||||
}
|
||||
private void setExampleTextFont(double size){
|
||||
setExampleTextFont(fontsLv.getSelectionModel().getSelectedItem(), size);
|
||||
}
|
||||
private void setExampleTextFont(String font, double size){
|
||||
exampleText.setFont(Font.font(font, size));
|
||||
}
|
||||
|
||||
private void reset(){
|
||||
final Font defaultFont = Font.getDefault();
|
||||
exampleText.setFont(defaultFont);
|
||||
|
||||
fontsLv.getSelectionModel().select(defaultFont.getFamily());
|
||||
fontSizeSpinner.getValueFactory().setValue(defaultFont.getSize());
|
||||
}
|
||||
|
||||
private void applyChanges(){
|
||||
final String fontFamily = fontsLv.getSelectionModel().getSelectedItem();
|
||||
final double fontSize = fontSizeSpinner.getValue().intValue();
|
||||
|
||||
preferences.setFontStyle(fontFamily, fontSize);
|
||||
|
||||
MediatorControl.INSTANCE.getLogArea().getScene().getRoot().setStyle(
|
||||
String.format("-fx-font-family: \"%s\"; -fx-font-size: %.0f;", fontFamily, fontSize));
|
||||
|
||||
closeWindow();
|
||||
}
|
||||
|
||||
private void closeWindow(){
|
||||
((Stage) cancelBtn.getScene().getWindow()).close();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko, wolfposd
|
||||
Copyright 2019-2020 Dmitry Isaenko, wolfposd
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -31,7 +31,6 @@ import javafx.scene.layout.Region;
|
|||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
import nsusbloader.AppPreferences;
|
||||
import nsusbloader.NSLDataTypes.EFileStatus;
|
||||
import nsusbloader.com.net.NETCommunications;
|
||||
import nsusbloader.com.usb.UsbCommunications;
|
||||
import nsusbloader.FilesHelper;
|
||||
|
@ -46,14 +45,12 @@ import java.util.*;
|
|||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class GamesController implements Initializable, ISubscriber {
|
||||
public class GamesController implements Initializable {
|
||||
|
||||
private static final String REGEX_ONLY_NSP = ".*\\.nsp$";
|
||||
private static final String REGEX_ALLFILES_TINFOIL = ".*\\.(nsp$|xci$|nsz$|xcz$)";
|
||||
private static final String REGEX_ALLFILES = ".*";
|
||||
|
||||
private static final MediatorControl mediator = MediatorControl.INSTANCE;
|
||||
|
||||
@FXML
|
||||
private AnchorPane usbNetPane;
|
||||
|
||||
|
@ -66,10 +63,10 @@ public class GamesController implements Initializable, ISubscriber {
|
|||
@FXML
|
||||
private Button switchThemeBtn;
|
||||
@FXML
|
||||
private NSTableViewController tableFilesListController;
|
||||
public NSTableViewController tableFilesListController; // Accessible from Mediator (for drag-n-drop support)
|
||||
|
||||
@FXML
|
||||
private Button selectNspBtn, selectSplitBtn, uploadStopBtn;
|
||||
private Button selectNspBtn, selectSplitNspBtn, uploadStopBtn;
|
||||
private String previouslyOpenedPath;
|
||||
private Region btnUpStopImage, btnSelectImage;
|
||||
private ResourceBundle resourceBundle;
|
||||
|
@ -104,7 +101,6 @@ public class GamesController implements Initializable, ISubscriber {
|
|||
disableUploadStopBtn(tableFilesListController.isFilesForUploadListEmpty());
|
||||
}); // Add listener to notify tableView controller
|
||||
tableFilesListController.setNewProtocol(getSelectedProtocolByName()); // Notify tableView controller
|
||||
tableFilesListController.setGamesController(this);
|
||||
|
||||
ObservableList<String> choiceNetUsbList = FXCollections.observableArrayList("USB", "NET");
|
||||
choiceNetUsb.setItems(choiceNetUsbList);
|
||||
|
@ -145,8 +141,8 @@ public class GamesController implements Initializable, ISubscriber {
|
|||
this.btnSelectImage = new Region();
|
||||
setFilesSelectorButtonBehaviour(preferences.getDirectoriesChooserForRoms());
|
||||
|
||||
selectSplitBtn.setOnAction(e-> selectSplitBtnAction());
|
||||
selectSplitBtn.getStyleClass().add("buttonSelect");
|
||||
selectSplitNspBtn.setOnAction(e-> selectSplitBtnAction());
|
||||
selectSplitNspBtn.getStyleClass().add("buttonSelect");
|
||||
|
||||
uploadStopBtn.setOnAction(e-> uploadBtnAction());
|
||||
uploadStopBtn.setDisable(isTinfoil());
|
||||
|
@ -208,11 +204,11 @@ public class GamesController implements Initializable, ISubscriber {
|
|||
}
|
||||
|
||||
private boolean isAllFiletypesAllowedForGL() {
|
||||
return ! mediator.getSettingsController().getGoldleafSettings().getNSPFileFilterForGL();
|
||||
return ! MediatorControl.getInstance().getSettingsController().getGoldleafSettings().getNSPFileFilterForGL();
|
||||
}
|
||||
|
||||
private boolean isXciNszXczSupport() {
|
||||
return mediator.getSettingsController().getTinfoilSettings().isXciNszXczSupport();
|
||||
return MediatorControl.getInstance().getSettingsController().getTinfoilSettings().isXciNszXczSupport();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -220,7 +216,7 @@ public class GamesController implements Initializable, ISubscriber {
|
|||
* tinfoil + xcinszxcz </br>
|
||||
* tinfoil + nsponly </br>
|
||||
* goldleaf </br>
|
||||
* etc...
|
||||
* etc..
|
||||
*/
|
||||
private String getRegexForFiles() {
|
||||
if (isTinfoil() && isXciNszXczSupport())
|
||||
|
@ -330,7 +326,7 @@ public class GamesController implements Initializable, ISubscriber {
|
|||
}
|
||||
|
||||
/**
|
||||
* Functionality for selecting Split-file button.
|
||||
* Functionality for selecting Split NSP button.
|
||||
* */
|
||||
private void selectSplitBtnAction(){
|
||||
File splitFile;
|
||||
|
@ -342,28 +338,11 @@ public class GamesController implements Initializable, ISubscriber {
|
|||
|
||||
splitFile = dirChooser.showDialog(usbNetPane.getScene().getWindow());
|
||||
|
||||
if (splitFile == null)
|
||||
return;
|
||||
|
||||
int fileNameLen = splitFile.getName().length();
|
||||
String fileExtension = splitFile.getName().toLowerCase().substring(fileNameLen-4, fileNameLen);
|
||||
|
||||
if (fileExtension.equals(".nsp")){
|
||||
if (splitFile != null && splitFile.getName().toLowerCase().endsWith(".nsp")) {
|
||||
tableFilesListController.setFile(splitFile);
|
||||
uploadStopBtn.setDisable(false); // Is it useful?
|
||||
previouslyOpenedPath = splitFile.getParent();
|
||||
}
|
||||
|
||||
if (isTinfoil() && isXciNszXczSupport()){
|
||||
switch(fileExtension){
|
||||
case ".xci":
|
||||
case ".nsz":
|
||||
case ".xcz":
|
||||
tableFilesListController.setFile(splitFile);
|
||||
uploadStopBtn.setDisable(false); // Is it useful?
|
||||
previouslyOpenedPath = splitFile.getParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* It's button listener when no transmission executes
|
||||
|
@ -372,33 +351,32 @@ public class GamesController implements Initializable, ISubscriber {
|
|||
if (workThread != null && workThread.isAlive())
|
||||
return;
|
||||
|
||||
// Collect files
|
||||
List<File> nspToUpload;
|
||||
|
||||
TextArea logArea = MediatorControl.getInstance().getContoller().logArea;
|
||||
|
||||
if (isTinfoil() && tableFilesListController.getFilesForUpload() == null) {
|
||||
ServiceWindow.getInfoNotification("(o_o\")", resourceBundle.getString("tab3_Txt_NoFolderOrFileSelected"));
|
||||
logArea.setText(resourceBundle.getString("tab3_Txt_NoFolderOrFileSelected"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Collect files
|
||||
List<File> nspToUpload = tableFilesListController.getFilesForUpload();
|
||||
|
||||
if (nspToUpload == null)
|
||||
nspToUpload = new ArrayList<>();
|
||||
//todo: add to make it visible
|
||||
/*
|
||||
else {
|
||||
TextArea logArea = mediator.getLogArea();
|
||||
if ((nspToUpload = tableFilesListController.getFilesForUpload()) != null){
|
||||
logArea.setText(resourceBundle.getString("tab3_Txt_FilesToUploadTitle")+"\n");
|
||||
nspToUpload.forEach(item -> logArea.appendText(" "+item.getAbsolutePath()+"\n"));
|
||||
}
|
||||
*/
|
||||
else {
|
||||
logArea.clear();
|
||||
nspToUpload = new LinkedList<>();
|
||||
}
|
||||
|
||||
SettingsController settings = mediator.getSettingsController();
|
||||
SettingsController settings = MediatorControl.getInstance().getSettingsController();
|
||||
// If USB selected
|
||||
if (isGoldLeaf()){
|
||||
final SettingsBlockGoldleafController goldleafSettings = settings.getGoldleafSettings();
|
||||
usbNetCommunications = new UsbCommunications(nspToUpload, "GoldLeaf" + goldleafSettings.getGlVer(), goldleafSettings.getNSPFileFilterForGL());
|
||||
}
|
||||
else {
|
||||
if (getSelectedNetUsb().equals("USB")){
|
||||
else if (( isTinfoil() && getSelectedNetUsb().equals("USB") )){
|
||||
usbNetCommunications = new UsbCommunications(nspToUpload, "TinFoil", false);
|
||||
}
|
||||
else { // NET INSTALL OVER TINFOIL
|
||||
|
@ -425,7 +403,6 @@ public class GamesController implements Initializable, ISubscriber {
|
|||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
workThread = new Thread(usbNetCommunications);
|
||||
workThread.setDaemon(true);
|
||||
workThread.start();
|
||||
|
@ -452,7 +429,7 @@ public class GamesController implements Initializable, ISubscriber {
|
|||
* */
|
||||
@FXML
|
||||
private void handleDragOver(DragEvent event){
|
||||
if (event.getDragboard().hasFiles() && ! mediator.getTransferActive())
|
||||
if (event.getDragboard().hasFiles() && ! MediatorControl.getInstance().getTransferActive())
|
||||
event.acceptTransferModes(TransferMode.ANY);
|
||||
event.consume();
|
||||
}
|
||||
|
@ -462,15 +439,47 @@ public class GamesController implements Initializable, ISubscriber {
|
|||
@FXML
|
||||
private void handleDrop(DragEvent event) {
|
||||
List<File> files = event.getDragboard().getFiles();
|
||||
new FilesDropHandle(files, getRegexForFiles(), getRegexForFolders(), tableFilesListController);
|
||||
new FilesDropHandle(files, getRegexForFiles(), getRegexForFolders());
|
||||
event.setDropCompleted(true);
|
||||
event.consume();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function called from NSTableViewController
|
||||
* This thing modify UI for reusing 'Upload to NS' button and make functionality set for "Stop transmission"
|
||||
* Called from mediator
|
||||
* TODO: remove shitcoding practices
|
||||
* */
|
||||
void disableUploadStopBtn(boolean disable){
|
||||
public void notifyThreadStarted(boolean isActive, EModule type){
|
||||
if (! type.equals(EModule.USB_NET_TRANSFERS)){
|
||||
usbNetPane.setDisable(isActive);
|
||||
return;
|
||||
}
|
||||
|
||||
selectNspBtn.setDisable(isActive);
|
||||
selectSplitNspBtn.setDisable(isActive);
|
||||
btnUpStopImage.getStyleClass().clear();
|
||||
|
||||
if (isActive) {
|
||||
btnUpStopImage.getStyleClass().add("regionStop");
|
||||
|
||||
uploadStopBtn.setOnAction(e-> stopBtnAction());
|
||||
uploadStopBtn.setText(resourceBundle.getString("btn_Stop"));
|
||||
uploadStopBtn.getStyleClass().remove("buttonUp");
|
||||
uploadStopBtn.getStyleClass().add("buttonStop");
|
||||
}
|
||||
else {
|
||||
btnUpStopImage.getStyleClass().add("regionUpload");
|
||||
|
||||
uploadStopBtn.setOnAction(e-> uploadBtnAction());
|
||||
uploadStopBtn.setText(resourceBundle.getString("btn_Upload"));
|
||||
uploadStopBtn.getStyleClass().remove("buttonStop");
|
||||
uploadStopBtn.getStyleClass().add("buttonUp");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Crunch. This function called from NSTableViewController
|
||||
* */
|
||||
public void disableUploadStopBtn(boolean disable){
|
||||
if (isTinfoil())
|
||||
uploadStopBtn.setDisable(disable);
|
||||
else
|
||||
|
@ -489,24 +498,27 @@ public class GamesController implements Initializable, ISubscriber {
|
|||
}).start();
|
||||
}
|
||||
|
||||
void setFilesSelectorButtonBehaviour(boolean isDirectoryChooser){
|
||||
public void updateFilesSelectorButtonBehaviour(boolean isDirectoryChooser){
|
||||
btnSelectImage.getStyleClass().clear();
|
||||
setFilesSelectorButtonBehaviour(isDirectoryChooser);
|
||||
}
|
||||
private void setFilesSelectorButtonBehaviour(boolean isDirectoryChooser){
|
||||
if (isDirectoryChooser){
|
||||
selectNspBtn.setOnAction(e -> selectFoldersBtnAction());
|
||||
btnSelectImage.getStyleClass().add("regionScanFolders");
|
||||
selectSplitBtn.setVisible(false);
|
||||
selectSplitNspBtn.setVisible(false);
|
||||
}
|
||||
else {
|
||||
selectNspBtn.setOnAction(e -> selectFilesBtnAction());
|
||||
btnSelectImage.getStyleClass().add("regionSelectFiles");
|
||||
selectSplitBtn.setVisible(true);
|
||||
selectSplitNspBtn.setVisible(true);
|
||||
}
|
||||
selectNspBtn.setGraphic(btnSelectImage);
|
||||
}
|
||||
/**
|
||||
* Get 'Recent' path
|
||||
*/
|
||||
private String getRecentPath(){
|
||||
public String getRecentPath(){
|
||||
return previouslyOpenedPath;
|
||||
}
|
||||
|
||||
|
@ -518,42 +530,4 @@ public class GamesController implements Initializable, ISubscriber {
|
|||
preferences.setNetUsb(getSelectedNetUsb());
|
||||
preferences.setNsIp(getNsIp());
|
||||
}
|
||||
|
||||
/**
|
||||
* This thing modifies UI for reusing 'Upload to NS' button and make functionality set for "Stop transmission"
|
||||
* */
|
||||
@Override
|
||||
public void notify(EModule type, boolean isActive, Payload payload) {
|
||||
if (! type.equals(EModule.USB_NET_TRANSFERS)){
|
||||
usbNetPane.setDisable(isActive);
|
||||
return;
|
||||
}
|
||||
|
||||
selectNspBtn.setDisable(isActive);
|
||||
selectSplitBtn.setDisable(isActive);
|
||||
btnUpStopImage.getStyleClass().clear();
|
||||
|
||||
if (isActive) {
|
||||
btnUpStopImage.getStyleClass().add("regionStop");
|
||||
|
||||
uploadStopBtn.setOnAction(e-> stopBtnAction());
|
||||
uploadStopBtn.setText(resourceBundle.getString("btn_Stop"));
|
||||
uploadStopBtn.getStyleClass().remove("buttonUp");
|
||||
uploadStopBtn.getStyleClass().add("buttonStop");
|
||||
return;
|
||||
}
|
||||
btnUpStopImage.getStyleClass().add("regionUpload");
|
||||
|
||||
uploadStopBtn.setOnAction(e-> uploadBtnAction());
|
||||
uploadStopBtn.setText(resourceBundle.getString("btn_Upload"));
|
||||
uploadStopBtn.getStyleClass().remove("buttonStop");
|
||||
uploadStopBtn.getStyleClass().add("buttonUp");
|
||||
|
||||
Map<String, EFileStatus> statusMap = payload.getStatusMap();
|
||||
|
||||
if (! statusMap.isEmpty()) {
|
||||
for (String key : statusMap.keySet())
|
||||
tableFilesListController.setFileStatus(key, statusMap.get(key));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Controllers;
|
||||
|
||||
import nsusbloader.NSLDataTypes.EModule;
|
||||
|
||||
public interface ISubscriber {
|
||||
void notify(EModule type, boolean status, Payload payload);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package nsusbloader.Controllers;
|
||||
|
||||
import javafx.application.HostServices;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
|
@ -34,15 +35,15 @@ public class NSLMainController implements Initializable {
|
|||
private ResourceBundle resourceBundle;
|
||||
|
||||
@FXML
|
||||
private TextArea logArea;
|
||||
public TextArea logArea; // Accessible from Mediator
|
||||
|
||||
@FXML
|
||||
private ProgressBar progressBar;
|
||||
public ProgressBar progressBar; // Accessible from Mediator
|
||||
|
||||
@FXML
|
||||
private TabPane mainTabPane;
|
||||
@FXML
|
||||
private Tab GamesTabHolder, RCMTabHolder, SMTabHolder, PatchesTabHolder;
|
||||
private Tab GamesTabHolder, RCMTabHolder, SMTabHolder;
|
||||
|
||||
@FXML
|
||||
private GamesController GamesTabController;
|
||||
|
@ -54,8 +55,6 @@ public class NSLMainController implements Initializable {
|
|||
private RcmController RcmTabController;
|
||||
@FXML
|
||||
private NxdtController NXDTabController;
|
||||
@FXML
|
||||
private PatchesController PatchesTabController;
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
|
@ -67,31 +66,13 @@ public class NSLMainController implements Initializable {
|
|||
|
||||
logArea.appendText(rb.getString("tab3_Txt_GreetingsMessage2")+"\n");
|
||||
|
||||
AppPreferences preferences = AppPreferences.getInstance();
|
||||
MediatorControl.getInstance().setController(this);
|
||||
|
||||
if (preferences.getAutoCheckUpdates())
|
||||
if (AppPreferences.getInstance().getAutoCheckUpdates()){
|
||||
checkForUpdates();
|
||||
|
||||
if (preferences.getPatchesTabInvisible())
|
||||
mainTabPane.getTabs().remove(3);
|
||||
}
|
||||
|
||||
openLastOpenedTab();
|
||||
|
||||
TransfersPublisher transfersPublisher = new TransfersPublisher(
|
||||
GamesTabController,
|
||||
SplitMergeTabController,
|
||||
RcmTabController,
|
||||
NXDTabController,
|
||||
PatchesTabController);
|
||||
|
||||
MediatorControl.INSTANCE.configure(
|
||||
resourceBundle,
|
||||
SettingsTabController,
|
||||
logArea,
|
||||
progressBar,
|
||||
GamesTabController,
|
||||
transfersPublisher);
|
||||
|
||||
}
|
||||
private void checkForUpdates(){
|
||||
Task<List<String>> updTask = new UpdatesChecker();
|
||||
|
@ -114,7 +95,38 @@ public class NSLMainController implements Initializable {
|
|||
updates.setDaemon(true);
|
||||
updates.start();
|
||||
}
|
||||
/**
|
||||
* Get resources
|
||||
* TODO: Find better solution; used in UsbCommunications() -> GL -> SelectFile command
|
||||
* @return ResourceBundle
|
||||
*/
|
||||
public ResourceBundle getResourceBundle() {
|
||||
return resourceBundle;
|
||||
}
|
||||
/**
|
||||
* Provide hostServices to Settings tab
|
||||
* */
|
||||
public void setHostServices(HostServices hs ){ SettingsTabController.getGenericSettings().registerHostServices(hs);}
|
||||
|
||||
/**
|
||||
* Get 'Settings' controller
|
||||
* Used by FrontController
|
||||
* */
|
||||
public SettingsController getSettingsCtrlr(){
|
||||
return SettingsTabController;
|
||||
}
|
||||
|
||||
public GamesController getGamesCtrlr(){
|
||||
return GamesTabController;
|
||||
}
|
||||
|
||||
public SplitMergeController getSmCtrlr(){
|
||||
return SplitMergeTabController;
|
||||
}
|
||||
|
||||
public RcmController getRcmCtrlr(){ return RcmTabController; }
|
||||
|
||||
public NxdtController getNXDTabController(){ return NXDTabController; }
|
||||
/**
|
||||
* Save preferences before exit
|
||||
* */
|
||||
|
@ -124,7 +136,7 @@ public class NSLMainController implements Initializable {
|
|||
SplitMergeTabController.updatePreferencesOnExit(); // NOTE: This shit above should be re-written to similar pattern
|
||||
RcmTabController.updatePreferencesOnExit();
|
||||
NXDTabController.updatePreferencesOnExit();
|
||||
PatchesTabController.updatePreferencesOnExit();
|
||||
|
||||
saveLastOpenedTab();
|
||||
}
|
||||
|
||||
|
@ -140,9 +152,6 @@ public class NSLMainController implements Initializable {
|
|||
case "SMTabHolder":
|
||||
mainTabPane.getSelectionModel().select(SMTabHolder);
|
||||
break;
|
||||
case "PatchesTabHolder":
|
||||
mainTabPane.getSelectionModel().select(PatchesTabHolder);
|
||||
break;
|
||||
}
|
||||
}
|
||||
private void saveLastOpenedTab(){
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko, wolfposd
|
||||
Copyright 2019-2020 Dmitry Isaenko, wolfposd
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -42,8 +42,6 @@ public class NSTableViewController implements Initializable {
|
|||
private TableView<NSLRowModel> table;
|
||||
private ObservableList<NSLRowModel> rowsObsLst;
|
||||
|
||||
private GamesController gamesController;
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
rowsObsLst = FXCollections.observableArrayList();
|
||||
|
@ -54,10 +52,10 @@ public class NSTableViewController implements Initializable {
|
|||
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
|
||||
table.setOnKeyPressed(keyEvent -> {
|
||||
if (!rowsObsLst.isEmpty()) {
|
||||
if (keyEvent.getCode() == KeyCode.DELETE && !MediatorControl.INSTANCE.getTransferActive()) {
|
||||
if (keyEvent.getCode() == KeyCode.DELETE && !MediatorControl.getInstance().getTransferActive()) {
|
||||
rowsObsLst.removeAll(table.getSelectionModel().getSelectedItems());
|
||||
if (rowsObsLst.isEmpty())
|
||||
gamesController.disableUploadStopBtn(true);
|
||||
MediatorControl.getInstance().getGamesController().disableUploadStopBtn(true); // TODO: change to something better
|
||||
table.refresh();
|
||||
} else if (keyEvent.getCode() == KeyCode.SPACE) {
|
||||
for (NSLRowModel item : table.getSelectionModel().getSelectedItems()) {
|
||||
|
@ -175,13 +173,13 @@ public class NSTableViewController implements Initializable {
|
|||
deleteMenuItem.setOnAction(actionEvent -> {
|
||||
rowsObsLst.remove(row.getItem());
|
||||
if (rowsObsLst.isEmpty())
|
||||
gamesController.disableUploadStopBtn(true);
|
||||
MediatorControl.getInstance().getGamesController().disableUploadStopBtn(true); // TODO: change to something better
|
||||
table.refresh();
|
||||
});
|
||||
MenuItem deleteAllMenuItem = new MenuItem(resourceBundle.getString("tab1_table_contextMenu_Btn_DeleteAll"));
|
||||
deleteAllMenuItem.setOnAction(actionEvent -> {
|
||||
rowsObsLst.clear();
|
||||
gamesController.disableUploadStopBtn(true);
|
||||
MediatorControl.getInstance().getGamesController().disableUploadStopBtn(true); // TODO: change to something better
|
||||
table.refresh();
|
||||
});
|
||||
contextMenu.getItems().addAll(deleteMenuItem, deleteAllMenuItem);
|
||||
|
@ -191,7 +189,7 @@ public class NSTableViewController implements Initializable {
|
|||
Bindings.when(
|
||||
Bindings.isNotNull(
|
||||
row.itemProperty()))
|
||||
.then(MediatorControl.INSTANCE.getTransferActive()?null:contextMenu)
|
||||
.then(MediatorControl.getInstance().getTransferActive()?null:contextMenu)
|
||||
.otherwise((ContextMenu) null)
|
||||
);
|
||||
// Just.. don't ask..
|
||||
|
@ -212,11 +210,6 @@ public class NSTableViewController implements Initializable {
|
|||
table.getColumns().add(fileSizeColumn);
|
||||
table.getColumns().add(uploadColumn);
|
||||
}
|
||||
|
||||
public void setGamesController(GamesController gamesController) {
|
||||
this.gamesController = gamesController;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add single file when user selected it (Split file usually)
|
||||
* */
|
||||
|
@ -231,7 +224,7 @@ public class NSTableViewController implements Initializable {
|
|||
}
|
||||
else {
|
||||
rowsObsLst.add(new NSLRowModel(file, true));
|
||||
gamesController.disableUploadStopBtn(false);
|
||||
MediatorControl.getInstance().getGamesController().disableUploadStopBtn(false); // TODO: change to something better
|
||||
}
|
||||
table.refresh();
|
||||
}
|
||||
|
@ -251,7 +244,7 @@ public class NSTableViewController implements Initializable {
|
|||
else {
|
||||
for (File file: newFiles)
|
||||
rowsObsLst.add(new NSLRowModel(file, true));
|
||||
gamesController.disableUploadStopBtn(false);
|
||||
MediatorControl.getInstance().getGamesController().disableUploadStopBtn(false); // TODO: change to something better
|
||||
}
|
||||
//rowsObsLst.get(0).setMarkForUpload(true);
|
||||
table.refresh();
|
||||
|
|
|
@ -25,6 +25,8 @@ import javafx.scene.control.Label;
|
|||
import javafx.scene.layout.Region;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import nsusbloader.AppPreferences;
|
||||
import nsusbloader.FilesHelper;
|
||||
import nsusbloader.MediatorControl;
|
||||
import nsusbloader.ModelControllers.CancellableRunnable;
|
||||
import nsusbloader.NSLDataTypes.EModule;
|
||||
import nsusbloader.Utilities.nxdumptool.NxdtTask;
|
||||
|
@ -33,7 +35,7 @@ import java.io.File;
|
|||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class NxdtController implements Initializable, ISubscriber {
|
||||
public class NxdtController implements Initializable {
|
||||
@FXML
|
||||
private Label saveToLocationLbl, statusLbl;
|
||||
|
||||
|
@ -77,6 +79,7 @@ public class NxdtController implements Initializable, ISubscriber {
|
|||
* */
|
||||
private void startDumpProcess(){
|
||||
if ((workThread == null || ! workThread.isAlive())){
|
||||
MediatorControl.getInstance().getContoller().logArea.clear();
|
||||
|
||||
nxdtTask = new NxdtTask(saveToLocationLbl.getText());
|
||||
workThread = new Thread(nxdtTask);
|
||||
|
@ -94,22 +97,12 @@ public class NxdtController implements Initializable, ISubscriber {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save application settings on exit
|
||||
* */
|
||||
public void updatePreferencesOnExit(){
|
||||
AppPreferences.getInstance().setNXDTSaveToLocation(saveToLocationLbl.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(EModule type, boolean isActive, Payload payload) {
|
||||
public void notifyThreadStarted(boolean isActive, EModule type){
|
||||
if (! type.equals(EModule.NXDT)){
|
||||
injectPldBtn.setDisable(isActive);
|
||||
return;
|
||||
}
|
||||
|
||||
statusLbl.setText(payload.getMessage());
|
||||
|
||||
if (isActive) {
|
||||
btnDumpStopImage.getStyleClass().clear();
|
||||
btnDumpStopImage.getStyleClass().add("regionStop");
|
||||
|
@ -128,4 +121,16 @@ public class NxdtController implements Initializable, ISubscriber {
|
|||
injectPldBtn.getStyleClass().remove("buttonStop");
|
||||
injectPldBtn.getStyleClass().add("buttonUp");
|
||||
}
|
||||
public void setOneLineStatus(boolean status){
|
||||
if (status)
|
||||
statusLbl.setText(rb.getString("done_txt"));
|
||||
else
|
||||
statusLbl.setText(rb.getString("failure_txt"));
|
||||
}
|
||||
/**
|
||||
* Save application settings on exit
|
||||
* */
|
||||
public void updatePreferencesOnExit(){
|
||||
AppPreferences.getInstance().setNXDTSaveToLocation(saveToLocationLbl.getText());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,343 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2024 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Controllers;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.input.DragEvent;
|
||||
import javafx.scene.input.TransferMode;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
import nsusbloader.AppPreferences;
|
||||
import nsusbloader.FilesHelper;
|
||||
import nsusbloader.MediatorControl;
|
||||
import nsusbloader.NSLDataTypes.EModule;
|
||||
import nsusbloader.ServiceWindow;
|
||||
import nsusbloader.Utilities.patches.es.EsPatchMaker;
|
||||
import nsusbloader.Utilities.patches.fs.FsPatchMaker;
|
||||
import nsusbloader.Utilities.patches.loader.LoaderPatchMaker;
|
||||
|
||||
// TODO: CLI SUPPORT
|
||||
public class PatchesController implements Initializable, ISubscriber {
|
||||
@FXML
|
||||
private VBox patchesToolPane;
|
||||
@FXML
|
||||
private Button makeEsBtn, makeFsBtn, makeLoaderBtn;
|
||||
@FXML
|
||||
private Label shortNameFirmwareLbl, locationFirmwareLbl, saveToLbl, shortNameKeysLbl, locationKeysLbl, statusLbl,
|
||||
locationAtmosphereLbl, shortNameAtmoLbl;
|
||||
private Thread workThread;
|
||||
|
||||
private String previouslyOpenedPath;
|
||||
private ResourceBundle resourceBundle;
|
||||
private Region convertRegionEs;
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.previouslyOpenedPath = System.getProperty("user.home");
|
||||
|
||||
String myRegexp;
|
||||
if (File.separator.equals("/"))
|
||||
myRegexp = "^.+/";
|
||||
else
|
||||
myRegexp = "^.+\\\\";
|
||||
locationFirmwareLbl.textProperty().addListener((observableValue, currentText, updatedText) ->
|
||||
shortNameFirmwareLbl.setText(updatedText.replaceAll(myRegexp, "")));
|
||||
|
||||
locationKeysLbl.textProperty().addListener((observableValue, currentText, updatedText) ->
|
||||
shortNameKeysLbl.setText(updatedText.replaceAll(myRegexp, "")));
|
||||
|
||||
locationAtmosphereLbl.textProperty().addListener((observableValue, currentText, updatedText) ->
|
||||
shortNameAtmoLbl.setText(updatedText.replaceAll(myRegexp, "")));
|
||||
|
||||
convertRegionEs = createCakeRegion();
|
||||
makeEsBtn.setGraphic(convertRegionEs);
|
||||
|
||||
makeFsBtn.setGraphic(createCakeRegion());
|
||||
makeLoaderBtn.setGraphic(createCakeRegion());
|
||||
|
||||
AppPreferences preferences = AppPreferences.getInstance();
|
||||
String keysLocation = preferences.getKeysLocation();
|
||||
File keysFile = new File(keysLocation);
|
||||
|
||||
if (keysFile.exists() && keysFile.isFile()) {
|
||||
locationKeysLbl.setText(keysLocation);
|
||||
}
|
||||
|
||||
saveToLbl.setText(preferences.getPatchesSaveToLocation());
|
||||
makeEsBtn.disableProperty().bind(Bindings.or(
|
||||
Bindings.isEmpty(locationFirmwareLbl.textProperty()),
|
||||
Bindings.isEmpty(locationKeysLbl.textProperty())));
|
||||
makeEsBtn.setOnAction(actionEvent -> makeEs());
|
||||
|
||||
makeFsBtn.disableProperty().bind(Bindings.or(
|
||||
Bindings.isEmpty(locationFirmwareLbl.textProperty()),
|
||||
Bindings.isEmpty(locationKeysLbl.textProperty())));
|
||||
makeFsBtn.setOnAction(actionEvent -> makeFs());
|
||||
|
||||
makeLoaderBtn.disableProperty().bind(Bindings.isEmpty(locationAtmosphereLbl.textProperty()));
|
||||
makeLoaderBtn.setOnAction(actionEvent -> makeLoader());
|
||||
}
|
||||
private Region createCakeRegion(){
|
||||
Region cakeRegion = new Region();
|
||||
cakeRegion.getStyleClass().add("regionCake");
|
||||
return cakeRegion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drag-n-drop support (dragOver consumer)
|
||||
* */
|
||||
@FXML
|
||||
private void handleDragOver(DragEvent event){
|
||||
if (event.getDragboard().hasFiles())
|
||||
event.acceptTransferModes(TransferMode.ANY);
|
||||
event.consume();
|
||||
}
|
||||
/**
|
||||
* Drag-n-drop support (drop consumer)
|
||||
* */
|
||||
@FXML
|
||||
private void handleDrop(DragEvent event){
|
||||
List<File> filesDropped = event.getDragboard().getFiles();
|
||||
for (File file : filesDropped){
|
||||
if (file.isDirectory()) {
|
||||
if (file.getName().toLowerCase().contains("atmosphe"))
|
||||
locationAtmosphereLbl.setText(file.getAbsolutePath());
|
||||
else
|
||||
locationFirmwareLbl.setText(file.getAbsolutePath());
|
||||
continue;
|
||||
}
|
||||
String fileName = file.getName().toLowerCase();
|
||||
if ((fileName.endsWith(".dat")) ||
|
||||
(fileName.endsWith(".keys") &&
|
||||
! fileName.equals("dev.keys") &&
|
||||
! fileName.equals("title.keys")))
|
||||
locationKeysLbl.setText(file.getAbsolutePath());
|
||||
else if (fileName.equals("offsets.txt"))
|
||||
setOffsets(file);
|
||||
}
|
||||
event.setDropCompleted(true);
|
||||
event.consume();
|
||||
}
|
||||
|
||||
private void setOffsets(File fileWithOffsets){
|
||||
AppPreferences preferences = AppPreferences.getInstance();
|
||||
int count = 0;
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(fileWithOffsets))) {
|
||||
String fileLine;
|
||||
String[] lineValues;
|
||||
while ((fileLine = reader.readLine()) != null) {
|
||||
if (fileLine.startsWith("#"))
|
||||
continue;
|
||||
lineValues = fileLine.trim().split("\\s+?=\\s+?", 2);
|
||||
if (lineValues.length == 2) {
|
||||
String[] pointer = lineValues[0].split("_", 3);
|
||||
if (! pointer[0].equals("ES") && ! pointer[0].equals("FS"))
|
||||
continue;
|
||||
if (! pointer[1].matches("^([0-9A-Fa-f]{2})$"))
|
||||
continue;
|
||||
if (! pointer[2].matches("^([0-9A-Fa-f]{2})$"))
|
||||
continue;
|
||||
if (! lineValues[1].matches("^(([0-9A-Fa-f]{2})|\\.)+?$"))
|
||||
continue;
|
||||
preferences.setPatchPattern(lineValues[0], lineValues[1]);
|
||||
|
||||
System.out.println(pointer[0]+"_"+pointer[1]+"_"+pointer[2]+" = "+lineValues[1]);
|
||||
count++;
|
||||
statusLbl.setText("OK "+count);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void selectFirmware(){
|
||||
DirectoryChooser directoryChooser = new DirectoryChooser();
|
||||
directoryChooser.setTitle(resourceBundle.getString("tabPatches_Lbl_Firmware"));
|
||||
directoryChooser.setInitialDirectory(new File(FilesHelper.getRealFolder(previouslyOpenedPath)));
|
||||
File firmware = directoryChooser.showDialog(patchesToolPane.getScene().getWindow());
|
||||
if (firmware == null)
|
||||
return;
|
||||
locationFirmwareLbl.setText(firmware.getAbsolutePath());
|
||||
previouslyOpenedPath = firmware.getParent();
|
||||
}
|
||||
@FXML
|
||||
private void selectAtmosphereFolder(){
|
||||
DirectoryChooser directoryChooser = new DirectoryChooser();
|
||||
directoryChooser.setTitle(resourceBundle.getString("tabPatches_Lbl_Atmo"));
|
||||
directoryChooser.setInitialDirectory(new File(FilesHelper.getRealFolder(previouslyOpenedPath)));
|
||||
File firmware = directoryChooser.showDialog(patchesToolPane.getScene().getWindow());
|
||||
if (firmware == null)
|
||||
return;
|
||||
locationAtmosphereLbl.setText(firmware.getAbsolutePath());
|
||||
previouslyOpenedPath = firmware.getParent();
|
||||
}
|
||||
@FXML
|
||||
private void selectSaveTo(){
|
||||
DirectoryChooser directoryChooser = new DirectoryChooser();
|
||||
directoryChooser.setTitle(resourceBundle.getString("tabSplMrg_Btn_SelectFolder"));
|
||||
directoryChooser.setInitialDirectory(new File(FilesHelper.getRealFolder(previouslyOpenedPath)));
|
||||
File saveToDir = directoryChooser.showDialog(patchesToolPane.getScene().getWindow());
|
||||
if (saveToDir == null)
|
||||
return;
|
||||
saveToLbl.setText(saveToDir.getAbsolutePath());
|
||||
}
|
||||
@FXML
|
||||
private void selectProdKeys(){
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.setTitle(resourceBundle.getString("tabPatches_Lbl_Keys"));
|
||||
fileChooser.setInitialDirectory(new File(FilesHelper.getRealFolder(previouslyOpenedPath)));
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("keys", "*.dat", "*.keys"));
|
||||
File keys = fileChooser.showOpenDialog(patchesToolPane.getScene().getWindow());
|
||||
if (keys == null || ! keys.exists())
|
||||
return;
|
||||
|
||||
locationKeysLbl.setText(keys.getAbsolutePath());
|
||||
previouslyOpenedPath = keys.getParent();
|
||||
}
|
||||
|
||||
private void makeEs(){
|
||||
if (locationFirmwareLbl.getText().isEmpty() || locationKeysLbl.getText().isEmpty()){
|
||||
ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"),
|
||||
resourceBundle.getString("tabPatches_ServiceWindowMessageEsFs"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (workThread != null && workThread.isAlive())
|
||||
return;
|
||||
|
||||
if (MediatorControl.INSTANCE.getTransferActive()) {
|
||||
ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"),
|
||||
resourceBundle.getString("windowBodyPleaseStopOtherProcessFirst"));
|
||||
return;
|
||||
}
|
||||
|
||||
EsPatchMaker esPatchMaker = new EsPatchMaker(locationFirmwareLbl.getText(), locationKeysLbl.getText(),
|
||||
saveToLbl.getText());
|
||||
workThread = new Thread(esPatchMaker);
|
||||
|
||||
workThread.setDaemon(true);
|
||||
workThread.start();
|
||||
}
|
||||
private void makeFs(){
|
||||
if (locationFirmwareLbl.getText().isEmpty() || locationKeysLbl.getText().isEmpty()){
|
||||
ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"),
|
||||
resourceBundle.getString("tabPatches_ServiceWindowMessageEsFs"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (workThread != null && workThread.isAlive())
|
||||
return;
|
||||
|
||||
if (MediatorControl.INSTANCE.getTransferActive()) {
|
||||
ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"),
|
||||
resourceBundle.getString("windowBodyPleaseStopOtherProcessFirst"));
|
||||
return;
|
||||
}
|
||||
|
||||
FsPatchMaker fsPatchMaker = new FsPatchMaker(locationFirmwareLbl.getText(), locationKeysLbl.getText(),
|
||||
saveToLbl.getText());
|
||||
workThread = new Thread(fsPatchMaker);
|
||||
|
||||
workThread.setDaemon(true);
|
||||
workThread.start();
|
||||
}
|
||||
private void makeLoader(){
|
||||
if (locationAtmosphereLbl.getText().isEmpty()){
|
||||
ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"),
|
||||
resourceBundle.getString("tabPatches_ServiceWindowMessageLoader"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (workThread != null && workThread.isAlive())
|
||||
return;
|
||||
|
||||
if (MediatorControl.INSTANCE.getTransferActive()) {
|
||||
ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"),
|
||||
resourceBundle.getString("windowBodyPleaseStopOtherProcessFirst"));
|
||||
return;
|
||||
}
|
||||
|
||||
LoaderPatchMaker loaderPatchMaker = new LoaderPatchMaker(locationAtmosphereLbl.getText(), saveToLbl.getText());
|
||||
workThread = new Thread(loaderPatchMaker);
|
||||
|
||||
workThread.setDaemon(true);
|
||||
workThread.start();
|
||||
}
|
||||
private void interruptProcessOfPatchMaking(){
|
||||
if (workThread == null || ! workThread.isAlive())
|
||||
return;
|
||||
|
||||
workThread.interrupt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(EModule type, boolean isActive, Payload payload) {
|
||||
if (! type.equals(EModule.PATCHES)) {
|
||||
patchesToolPane.setDisable(isActive);
|
||||
return;
|
||||
}
|
||||
|
||||
statusLbl.setText(payload.getMessage());
|
||||
|
||||
convertRegionEs.getStyleClass().clear();
|
||||
makeFsBtn.setVisible(! isActive);
|
||||
makeLoaderBtn.setVisible(! isActive);
|
||||
|
||||
if (isActive) {
|
||||
convertRegionEs.getStyleClass().add("regionStop");
|
||||
|
||||
makeEsBtn.setOnAction(e-> interruptProcessOfPatchMaking());
|
||||
makeEsBtn.setText(resourceBundle.getString("btn_Stop"));
|
||||
makeEsBtn.getStyleClass().remove("buttonUp");
|
||||
makeEsBtn.getStyleClass().add("buttonStop");
|
||||
return;
|
||||
}
|
||||
convertRegionEs.getStyleClass().add("regionCake");
|
||||
|
||||
makeEsBtn.setOnAction(actionEvent -> makeEs());
|
||||
makeEsBtn.setText(resourceBundle.getString("tabPatches_Btn_MakeEs"));
|
||||
makeEsBtn.getStyleClass().remove("buttonStop");
|
||||
makeEsBtn.getStyleClass().add("buttonUp");
|
||||
}
|
||||
|
||||
void updatePreferencesOnExit(){
|
||||
AppPreferences.getInstance().setPatchesSaveToLocation(saveToLbl.getText());
|
||||
if (locationKeysLbl.getText().isEmpty())
|
||||
return;
|
||||
AppPreferences.getInstance().setKeysLocation(locationKeysLbl.getText());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Controllers;
|
||||
|
||||
import nsusbloader.NSLDataTypes.EFileStatus;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
public class Payload {
|
||||
private final String message;
|
||||
private final Map<String, EFileStatus> statusMap;
|
||||
|
||||
public Payload(){
|
||||
this("");
|
||||
}
|
||||
public Payload(String message){
|
||||
this(message, Collections.emptyMap());
|
||||
}
|
||||
public Payload(String message, Map<String, EFileStatus> statusMap){
|
||||
this.message = message;
|
||||
this.statusMap = statusMap;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Map<String, EFileStatus> getStatusMap() {
|
||||
return statusMap;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -41,7 +41,7 @@ import java.io.File;
|
|||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class RcmController implements Initializable, ISubscriber {
|
||||
public class RcmController implements Initializable {
|
||||
@FXML
|
||||
private ToggleGroup rcmToggleGrp;
|
||||
|
||||
|
@ -68,14 +68,12 @@ public class RcmController implements Initializable, ISubscriber {
|
|||
@FXML
|
||||
private Label statusLbl;
|
||||
|
||||
private AppPreferences preferences;
|
||||
private ResourceBundle rb;
|
||||
private String myRegexp;
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
this.rb = resourceBundle;
|
||||
this.preferences = AppPreferences.getInstance();
|
||||
final AppPreferences preferences = AppPreferences.getInstance();
|
||||
|
||||
rcmToggleGrp.selectToggle(pldrRadio1);
|
||||
pldrRadio1.setOnAction(e -> statusLbl.setText(""));
|
||||
|
@ -195,7 +193,8 @@ public class RcmController implements Initializable, ISubscriber {
|
|||
}
|
||||
|
||||
private void smash(){
|
||||
if (MediatorControl.INSTANCE.getTransferActive()) {
|
||||
statusLbl.setText("");
|
||||
if (MediatorControl.getInstance().getTransferActive()) {
|
||||
ServiceWindow.getErrorNotification(rb.getString("windowTitleError"),
|
||||
rb.getString("windowBodyPleaseStopOtherProcessFirst"));
|
||||
return;
|
||||
|
@ -274,28 +273,31 @@ public class RcmController implements Initializable, ISubscriber {
|
|||
private void bntResetPayloader(ActionEvent event){
|
||||
final Node btn = (Node)event.getSource();
|
||||
|
||||
statusLbl.setText("");
|
||||
|
||||
switch (btn.getId()){
|
||||
case "resPldBtn1":
|
||||
payloadFNameLbl1.setText("");
|
||||
payloadFPathLbl1.setText("");
|
||||
statusLbl.setText("");
|
||||
break;
|
||||
case "resPldBtn2":
|
||||
payloadFNameLbl2.setText("");
|
||||
payloadFPathLbl2.setText("");
|
||||
statusLbl.setText("");
|
||||
break;
|
||||
case "resPldBtn3":
|
||||
payloadFNameLbl3.setText("");
|
||||
payloadFPathLbl3.setText("");
|
||||
statusLbl.setText("");
|
||||
break;
|
||||
case "resPldBtn4":
|
||||
payloadFNameLbl4.setText("");
|
||||
payloadFPathLbl4.setText("");
|
||||
statusLbl.setText("");
|
||||
break;
|
||||
case "resPldBtn5":
|
||||
payloadFNameLbl5.setText("");
|
||||
payloadFPathLbl5.setText("");
|
||||
statusLbl.setText("");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,20 +324,27 @@ public class RcmController implements Initializable, ISubscriber {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(EModule type, boolean isActive, Payload payload) {
|
||||
rcmToolPane.setDisable(isActive);
|
||||
if (type.equals(EModule.RCM))
|
||||
statusLbl.setText(payload.getMessage());
|
||||
public void setOneLineStatus(boolean statusSuccess){
|
||||
if (statusSuccess)
|
||||
statusLbl.setText(rb.getString("done_txt"));
|
||||
else
|
||||
statusLbl.setText(rb.getString("failure_txt"));
|
||||
}
|
||||
|
||||
public void notifyThreadStarted(boolean isStart, EModule type){
|
||||
rcmToolPane.setDisable(isStart);
|
||||
if (type.equals(EModule.RCM) && isStart){
|
||||
MediatorControl.getInstance().getContoller().logArea.clear();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Save application settings on exit
|
||||
* */
|
||||
public void updatePreferencesOnExit(){
|
||||
preferences.setRecentRcm(1, payloadFPathLbl1.getText());
|
||||
preferences.setRecentRcm(2, payloadFPathLbl2.getText());
|
||||
preferences.setRecentRcm(3, payloadFPathLbl3.getText());
|
||||
preferences.setRecentRcm(4, payloadFPathLbl4.getText());
|
||||
preferences.setRecentRcm(5, payloadFPathLbl5.getText());
|
||||
AppPreferences.getInstance().setRecentRcm(1, payloadFPathLbl1.getText());
|
||||
AppPreferences.getInstance().setRecentRcm(2, payloadFPathLbl2.getText());
|
||||
AppPreferences.getInstance().setRecentRcm(3, payloadFPathLbl3.getText());
|
||||
AppPreferences.getInstance().setRecentRcm(4, payloadFPathLbl4.getText());
|
||||
AppPreferences.getInstance().setRecentRcm(5, payloadFPathLbl5.getText());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -43,9 +43,6 @@ import java.util.ResourceBundle;
|
|||
public class SettingsBlockGenericController implements Initializable {
|
||||
@FXML
|
||||
private ChoiceBox<LocaleHolder> languagesChB;
|
||||
@FXML
|
||||
private Button fontSelectBtn;
|
||||
|
||||
@FXML
|
||||
private Button submitLanguageBtn,
|
||||
driversInstallBtn,
|
||||
|
@ -55,7 +52,9 @@ public class SettingsBlockGenericController implements Initializable {
|
|||
direcroriesChooserForRomsCB;
|
||||
@FXML
|
||||
private Hyperlink newVersionHyperlink;
|
||||
|
||||
private ResourceBundle resourceBundle;
|
||||
|
||||
private HostServices hostServices;
|
||||
|
||||
@Override
|
||||
|
@ -66,7 +65,7 @@ public class SettingsBlockGenericController implements Initializable {
|
|||
autoCheckForUpdatesCB.setSelected(preferences.getAutoCheckUpdates());
|
||||
direcroriesChooserForRomsCB.setSelected(preferences.getDirectoriesChooserForRoms());
|
||||
direcroriesChooserForRomsCB.setOnAction(actionEvent ->
|
||||
MediatorControl.INSTANCE.getGamesController().setFilesSelectorButtonBehaviour(direcroriesChooserForRomsCB.isSelected())
|
||||
MediatorControl.getInstance().getGamesController().updateFilesSelectorButtonBehaviour(direcroriesChooserForRomsCB.isSelected())
|
||||
);
|
||||
|
||||
Region btnSwitchImage = new Region();
|
||||
|
@ -79,18 +78,9 @@ public class SettingsBlockGenericController implements Initializable {
|
|||
languagesChB.setItems(settingsLanguagesSetup.getLanguages());
|
||||
languagesChB.getSelectionModel().select(settingsLanguagesSetup.getRecentLanguage());
|
||||
|
||||
hostServices = MediatorControl.INSTANCE.getHostServices();
|
||||
newVersionHyperlink.setOnAction(e-> hostServices.showDocument(newVersionHyperlink.getText()));
|
||||
checkForUpdBtn.setOnAction(e->checkForUpdatesAction());
|
||||
submitLanguageBtn.setOnAction(e->languageButtonAction());
|
||||
fontSelectBtn.setOnAction(e -> openFontSettings());
|
||||
}
|
||||
private void openFontSettings() {
|
||||
try {
|
||||
new FontSettings(resourceBundle);
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void setDriversInstallFeature(){
|
||||
|
@ -148,6 +138,8 @@ public class SettingsBlockGenericController implements Initializable {
|
|||
return direcroriesChooserForRomsCB.isSelected();
|
||||
}
|
||||
|
||||
protected void registerHostServices(HostServices hostServices){ this.hostServices = hostServices;}
|
||||
|
||||
void setNewVersionLink(String newVer){
|
||||
newVersionHyperlink.setVisible(true);
|
||||
newVersionHyperlink.setText("https://github.com/developersu/ns-usbloader/releases/tag/"+newVer);
|
||||
|
|
|
@ -38,7 +38,7 @@ public class SettingsBlockGoldleafController implements Initializable {
|
|||
final AppPreferences preferences = AppPreferences.getInstance();
|
||||
|
||||
nspFilesFilterForGLCB.setSelected(preferences.getNspFileFilterGL());
|
||||
glVersionChoiceBox.getItems().addAll(AppPreferences.GOLDLEAF_SUPPORTED_VERSIONS);
|
||||
glVersionChoiceBox.getItems().addAll(AppPreferences.goldleafSupportedVersions);
|
||||
|
||||
glVersionChoiceBox.getSelectionModel().select(preferences.getGlVersion());
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ public class SettingsBlockTinfoilController implements Initializable {
|
|||
|
||||
final AppPreferences preferences = AppPreferences.getInstance();
|
||||
|
||||
networkExpertSettingsVBox.visibleProperty().bind(networkExpertModeCB.selectedProperty());
|
||||
networkExpertSettingsVBox.disableProperty().bind(networkExpertModeCB.selectedProperty().not());
|
||||
|
||||
pcIpTF.disableProperty().bind(autoDetectIpCB.selectedProperty());
|
||||
pcPortTF.disableProperty().bind(randomlySelectPortCB.selectedProperty());
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -31,6 +31,7 @@ import javafx.stage.FileChooser;
|
|||
import nsusbloader.AppPreferences;
|
||||
import nsusbloader.FilesHelper;
|
||||
import nsusbloader.MediatorControl;
|
||||
import nsusbloader.ModelControllers.CancellableRunnable;
|
||||
import nsusbloader.NSLDataTypes.EModule;
|
||||
import nsusbloader.ServiceWindow;
|
||||
import nsusbloader.Utilities.splitmerge.SplitMergeTaskExecutor;
|
||||
|
@ -40,7 +41,7 @@ import java.net.URL;
|
|||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class SplitMergeController implements Initializable, ISubscriber {
|
||||
public class SplitMergeController implements Initializable {
|
||||
@FXML
|
||||
private ToggleGroup splitMergeTogGrp;
|
||||
@FXML
|
||||
|
@ -146,87 +147,13 @@ public class SplitMergeController implements Initializable, ISubscriber {
|
|||
convertBtn.setOnAction(actionEvent -> setConvertBtnAction());
|
||||
}
|
||||
|
||||
/**
|
||||
* It's button listener when convert-process in progress
|
||||
* */
|
||||
private void stopBtnAction(){
|
||||
if (smThread != null && smThread.isAlive()) {
|
||||
smThread.interrupt();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* It's button listener when convert-process NOT in progress
|
||||
* */
|
||||
private void setConvertBtnAction(){
|
||||
if (MediatorControl.INSTANCE.getTransferActive()) {
|
||||
ServiceWindow.getErrorNotification(
|
||||
resourceBundle.getString("windowTitleError"),
|
||||
resourceBundle.getString("windowBodyPleaseFinishTransfersFirst")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (splitRad.isSelected())
|
||||
smTask = new SplitMergeTaskExecutor(true, BlockListViewController.getItems(), saveToPathLbl.getText());
|
||||
else
|
||||
smTask = new SplitMergeTaskExecutor(false, BlockListViewController.getItems(), saveToPathLbl.getText());
|
||||
smThread = new Thread(smTask);
|
||||
smThread.setDaemon(true);
|
||||
smThread.start();
|
||||
}
|
||||
/**
|
||||
* Drag-n-drop support (dragOver consumer)
|
||||
* */
|
||||
@FXML
|
||||
private void handleDragOver(DragEvent event){
|
||||
if (event.getDragboard().hasFiles() && ! MediatorControl.INSTANCE.getTransferActive())
|
||||
event.acceptTransferModes(TransferMode.ANY);
|
||||
event.consume();
|
||||
}
|
||||
/**
|
||||
* Drag-n-drop support (drop consumer)
|
||||
* */
|
||||
@FXML
|
||||
private void handleDrop(DragEvent event) {
|
||||
List<File> files = event.getDragboard().getFiles();
|
||||
File firstFile = files.get(0);
|
||||
|
||||
if (firstFile.isDirectory())
|
||||
mergeRad.fire();
|
||||
else
|
||||
splitRad.fire();
|
||||
|
||||
this.BlockListViewController.addAll(files);
|
||||
|
||||
event.setDropCompleted(true);
|
||||
event.consume();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save application settings on exit
|
||||
* */
|
||||
public void updatePreferencesOnExit(){
|
||||
if (splitRad.isSelected())
|
||||
AppPreferences.getInstance().setSplitMergeType(0);
|
||||
else
|
||||
AppPreferences.getInstance().setSplitMergeType(1);
|
||||
|
||||
AppPreferences.getInstance().setSplitMergeRecent(saveToPathLbl.getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(EModule type, boolean isActive, Payload payload) {
|
||||
// todo: refactor: remove everything, place to separate container and just disable.
|
||||
|
||||
public void notifyThreadStarted(boolean isStart, EModule type){ // todo: refactor: remove everything, place to separate container and just disable.
|
||||
if (! type.equals(EModule.SPLIT_MERGE_TOOL)){
|
||||
smToolPane.setDisable(isActive);
|
||||
smToolPane.setDisable(isStart);
|
||||
return;
|
||||
}
|
||||
|
||||
statusLbl.setText(payload.getMessage());
|
||||
|
||||
if (isActive){
|
||||
if (isStart){
|
||||
MediatorControl.getInstance().getContoller().logArea.clear();
|
||||
splitRad.setDisable(true);
|
||||
mergeRad.setDisable(true);
|
||||
selectFileFolderBtn.setDisable(true);
|
||||
|
@ -255,4 +182,79 @@ public class SplitMergeController implements Initializable, ISubscriber {
|
|||
else
|
||||
convertRegion.getStyleClass().add("regionOneToSplit");
|
||||
}
|
||||
|
||||
/**
|
||||
* It's button listener when convert-process in progress
|
||||
* */
|
||||
private void stopBtnAction(){
|
||||
if (smThread != null && smThread.isAlive()) {
|
||||
smThread.interrupt();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* It's button listener when convert-process NOT in progress
|
||||
* */
|
||||
private void setConvertBtnAction(){
|
||||
statusLbl.setText("");
|
||||
if (MediatorControl.getInstance().getTransferActive()) {
|
||||
ServiceWindow.getErrorNotification(
|
||||
resourceBundle.getString("windowTitleError"),
|
||||
resourceBundle.getString("windowBodyPleaseFinishTransfersFirst")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (splitRad.isSelected())
|
||||
smTask = new SplitMergeTaskExecutor(true, BlockListViewController.getItems(), saveToPathLbl.getText());
|
||||
else
|
||||
smTask = new SplitMergeTaskExecutor(false, BlockListViewController.getItems(), saveToPathLbl.getText());
|
||||
smThread = new Thread(smTask);
|
||||
smThread.setDaemon(true);
|
||||
smThread.start();
|
||||
}
|
||||
/**
|
||||
* Drag-n-drop support (dragOver consumer)
|
||||
* */
|
||||
@FXML
|
||||
private void handleDragOver(DragEvent event){
|
||||
if (event.getDragboard().hasFiles() && ! MediatorControl.getInstance().getTransferActive())
|
||||
event.acceptTransferModes(TransferMode.ANY);
|
||||
event.consume();
|
||||
}
|
||||
/**
|
||||
* Drag-n-drop support (drop consumer)
|
||||
* */
|
||||
@FXML
|
||||
private void handleDrop(DragEvent event) {
|
||||
List<File> files = event.getDragboard().getFiles();
|
||||
File firstFile = files.get(0);
|
||||
|
||||
if (firstFile.isDirectory())
|
||||
mergeRad.fire();
|
||||
else
|
||||
splitRad.fire();
|
||||
|
||||
this.BlockListViewController.addAll(files);
|
||||
|
||||
event.setDropCompleted(true);
|
||||
event.consume();
|
||||
}
|
||||
|
||||
public void setOneLineStatus(boolean status){
|
||||
if (status)
|
||||
statusLbl.setText(resourceBundle.getString("done_txt"));
|
||||
else
|
||||
statusLbl.setText(resourceBundle.getString("failure_txt"));
|
||||
}
|
||||
/**
|
||||
* Save application settings on exit
|
||||
* */
|
||||
public void updatePreferencesOnExit(){
|
||||
if (splitRad.isSelected())
|
||||
AppPreferences.getInstance().setSplitMergeType(0);
|
||||
else
|
||||
AppPreferences.getInstance().setSplitMergeType(1);
|
||||
|
||||
AppPreferences.getInstance().setSplitMergeRecent(saveToPathLbl.getText());
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -18,57 +18,44 @@
|
|||
*/
|
||||
package nsusbloader;
|
||||
|
||||
import javafx.application.HostServices;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
import javafx.scene.control.TextArea;
|
||||
import nsusbloader.Controllers.*;
|
||||
import nsusbloader.NSLDataTypes.EModule;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class MediatorControl {
|
||||
public static final MediatorControl INSTANCE = new MediatorControl();
|
||||
private final AtomicBoolean isTransferActive = new AtomicBoolean(false); // Overcoded just for sure
|
||||
private NSLMainController mainController;
|
||||
|
||||
private ResourceBundle resourceBundle;
|
||||
private TransfersPublisher transfersPublisher;
|
||||
private HostServices hostServices;
|
||||
private GamesController gamesController;
|
||||
private SettingsController settingsController;
|
||||
|
||||
private TextArea logArea;
|
||||
private ProgressBar progressBar;
|
||||
|
||||
private MediatorControl(){}
|
||||
|
||||
public void configure(ResourceBundle resourceBundle,
|
||||
SettingsController settingsController,
|
||||
TextArea logArea,
|
||||
ProgressBar progressBar,
|
||||
GamesController gamesController,
|
||||
TransfersPublisher transfersPublisher) {
|
||||
this.resourceBundle = resourceBundle;
|
||||
this.settingsController = settingsController;
|
||||
this.gamesController = gamesController;
|
||||
this.logArea = logArea;
|
||||
this.progressBar = progressBar;
|
||||
this.transfersPublisher = transfersPublisher;
|
||||
}
|
||||
public void setHostServices(HostServices hostServices) {
|
||||
this.hostServices = hostServices;
|
||||
public static MediatorControl getInstance(){
|
||||
return MediatorControlHold.INSTANCE;
|
||||
}
|
||||
|
||||
public HostServices getHostServices() { return hostServices; }
|
||||
public ResourceBundle getResourceBundle(){ return resourceBundle; }
|
||||
public SettingsController getSettingsController() { return settingsController; }
|
||||
public GamesController getGamesController() { return gamesController; }
|
||||
public TextArea getLogArea() { return logArea; }
|
||||
public ProgressBar getProgressBar() { return progressBar; }
|
||||
|
||||
public synchronized void setTransferActive(EModule appModuleType, boolean isActive, Payload payload) {
|
||||
transfersPublisher.setTransferActive(appModuleType, isActive, payload);
|
||||
private static class MediatorControlHold {
|
||||
private static final MediatorControl INSTANCE = new MediatorControl();
|
||||
}
|
||||
public void setController(NSLMainController controller){
|
||||
this.mainController = controller;
|
||||
}
|
||||
|
||||
public synchronized boolean getTransferActive() {
|
||||
return transfersPublisher.getTransferActive();
|
||||
public NSLMainController getContoller(){ return mainController; }
|
||||
public GamesController getGamesController(){ return mainController.getGamesCtrlr(); };
|
||||
public SettingsController getSettingsController(){ return mainController.getSettingsCtrlr(); };
|
||||
public SplitMergeController getSplitMergeController(){ return mainController.getSmCtrlr(); };
|
||||
public RcmController getRcmController(){ return mainController.getRcmCtrlr(); };
|
||||
public NxdtController getNxdtController(){ return mainController.getNXDTabController(); };
|
||||
|
||||
public ResourceBundle getResourceBundle(){
|
||||
return mainController.getResourceBundle();
|
||||
}
|
||||
|
||||
public synchronized void setBgThreadActive(boolean isActive, EModule appModuleType) {
|
||||
isTransferActive.set(isActive);
|
||||
getGamesController().notifyThreadStarted(isActive, appModuleType);
|
||||
getSplitMergeController().notifyThreadStarted(isActive, appModuleType);
|
||||
getRcmController().notifyThreadStarted(isActive, appModuleType);
|
||||
getNxdtController().notifyThreadStarted(isActive, appModuleType);
|
||||
}
|
||||
public synchronized boolean getTransferActive() { return this.isTransferActive.get(); }
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -42,11 +42,7 @@ public class LogPrinterGui implements ILogPrinter {
|
|||
this.progressQueue = new LinkedBlockingQueue<>();
|
||||
this.statusMap = new HashMap<>();
|
||||
this.oneLinerStatus = new AtomicBoolean();
|
||||
this.msgConsumer = new MessagesConsumer(whoIsAsking,
|
||||
this.msgQueue,
|
||||
this.progressQueue,
|
||||
this.statusMap,
|
||||
this.oneLinerStatus);
|
||||
this.msgConsumer = new MessagesConsumer(whoIsAsking, this.msgQueue, this.progressQueue, this.statusMap, this.oneLinerStatus);
|
||||
this.msgConsumer.start();
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -22,26 +22,24 @@ import javafx.animation.AnimationTimer;
|
|||
import javafx.scene.control.ProgressBar;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
import javafx.scene.control.TextArea;
|
||||
import nsusbloader.Controllers.Payload;
|
||||
import nsusbloader.Controllers.NSTableViewController;
|
||||
import nsusbloader.MediatorControl;
|
||||
import nsusbloader.NSLDataTypes.EFileStatus;
|
||||
import nsusbloader.NSLDataTypes.EModule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class MessagesConsumer extends AnimationTimer {
|
||||
private static final MediatorControl mediator = MediatorControl.INSTANCE;
|
||||
private static final TextArea logsArea = mediator.getLogArea();
|
||||
private static final ProgressBar progressBar = mediator.getProgressBar();;
|
||||
private static final ResourceBundle resourceBundle = mediator.getResourceBundle();
|
||||
|
||||
private final BlockingQueue<String> msgQueue;
|
||||
private final TextArea logsArea;
|
||||
|
||||
private final BlockingQueue<Double> progressQueue;
|
||||
private final ProgressBar progressBar;
|
||||
private final HashMap<String, EFileStatus> statusMap;
|
||||
private final NSTableViewController tableViewController;
|
||||
private final EModule appModuleType;
|
||||
|
||||
private final AtomicBoolean oneLinerStatus;
|
||||
|
@ -55,16 +53,22 @@ public class MessagesConsumer extends AnimationTimer {
|
|||
AtomicBoolean oneLinerStatus){
|
||||
this.appModuleType = appModuleType;
|
||||
this.isInterrupted = false;
|
||||
|
||||
this.msgQueue = msgQueue;
|
||||
this.logsArea = MediatorControl.getInstance().getContoller().logArea;
|
||||
|
||||
this.progressQueue = progressQueue;
|
||||
this.progressBar = MediatorControl.getInstance().getContoller().progressBar;
|
||||
|
||||
this.statusMap = statusMap;
|
||||
this.tableViewController = MediatorControl.getInstance().getGamesController().tableFilesListController;
|
||||
|
||||
this.oneLinerStatus = oneLinerStatus;
|
||||
|
||||
progressBar.setProgress(0.0);
|
||||
progressBar.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
|
||||
|
||||
logsArea.clear();
|
||||
mediator.setTransferActive(appModuleType, true, new Payload());
|
||||
progressBar.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
|
||||
MediatorControl.getInstance().setBgThreadActive(true, appModuleType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -85,18 +89,30 @@ public class MessagesConsumer extends AnimationTimer {
|
|||
});
|
||||
}
|
||||
|
||||
if (isInterrupted) // safe, could not be interrupted while HashMap populating
|
||||
if (isInterrupted) // It's safe 'cuz it's could't be interrupted while HashMap populating
|
||||
updateElementsAndStop();
|
||||
}
|
||||
|
||||
private void updateElementsAndStop(){
|
||||
Payload payload = new Payload(
|
||||
resourceBundle.getString(oneLinerStatus.get() ? "done_txt" : "failure_txt"),
|
||||
statusMap);
|
||||
|
||||
mediator.setTransferActive(appModuleType, false, payload);
|
||||
MediatorControl.getInstance().setBgThreadActive(false, appModuleType);
|
||||
progressBar.setProgress(0.0);
|
||||
|
||||
if (statusMap.size() > 0){
|
||||
for (String key : statusMap.keySet())
|
||||
tableViewController.setFileStatus(key, statusMap.get(key));
|
||||
}
|
||||
|
||||
switch (appModuleType){
|
||||
case RCM:
|
||||
MediatorControl.getInstance().getRcmController().setOneLineStatus(oneLinerStatus.get());
|
||||
break;
|
||||
case NXDT:
|
||||
MediatorControl.getInstance().getNxdtController().setOneLineStatus(oneLinerStatus.get());
|
||||
break;
|
||||
case SPLIT_MERGE_TOOL:
|
||||
MediatorControl.getInstance().getSplitMergeController().setOneLineStatus(oneLinerStatus.get());
|
||||
break;
|
||||
}
|
||||
this.stop();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,5 @@ public enum EModule {
|
|||
USB_NET_TRANSFERS,
|
||||
SPLIT_MERGE_TOOL,
|
||||
RCM,
|
||||
NXDT,
|
||||
PATCHES
|
||||
NXDT
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -28,7 +28,6 @@ import nsusbloader.Controllers.NSLMainController;
|
|||
import nsusbloader.cli.CommandLineInterface;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class NSLMain extends Application {
|
||||
|
@ -42,15 +41,16 @@ public class NSLMain extends Application {
|
|||
|
||||
Locale userLocale = AppPreferences.getInstance().getLocale();
|
||||
ResourceBundle rb = ResourceBundle.getBundle("locale", userLocale);
|
||||
NSLMain.appVersion = ResourceBundle.getBundle("app").getString("_version");
|
||||
|
||||
loader.setResources(rb);
|
||||
Parent root = loader.load();
|
||||
|
||||
primaryStage.getIcons().addAll(
|
||||
new Image(Objects.requireNonNull(getClass().getResourceAsStream("/res/app_icon32x32.png"))),
|
||||
new Image(Objects.requireNonNull(getClass().getResourceAsStream("/res/app_icon48x48.png"))),
|
||||
new Image(Objects.requireNonNull(getClass().getResourceAsStream("/res/app_icon64x64.png"))),
|
||||
new Image(Objects.requireNonNull(getClass().getResourceAsStream("/res/app_icon128x128.png")))
|
||||
new Image(getClass().getResourceAsStream("/res/app_icon32x32.png")),
|
||||
new Image(getClass().getResourceAsStream("/res/app_icon48x48.png")),
|
||||
new Image(getClass().getResourceAsStream("/res/app_icon64x64.png")),
|
||||
new Image(getClass().getResourceAsStream("/res/app_icon128x128.png"))
|
||||
);
|
||||
|
||||
primaryStage.setTitle("NS-USBloader "+appVersion);
|
||||
|
@ -62,21 +62,19 @@ public class NSLMain extends Application {
|
|||
);
|
||||
|
||||
mainScene.getStylesheets().add(AppPreferences.getInstance().getTheme());
|
||||
root.setStyle(AppPreferences.getInstance().getFontStyle());
|
||||
|
||||
primaryStage.setScene(mainScene);
|
||||
primaryStage.show();
|
||||
|
||||
primaryStage.setOnCloseRequest(e->{
|
||||
if (MediatorControl.INSTANCE.getTransferActive())
|
||||
if (MediatorControl.getInstance().getTransferActive())
|
||||
if(! ServiceWindow.getConfirmationWindow(rb.getString("windowTitleConfirmExit"),
|
||||
rb.getString("windowBodyConfirmExit")))
|
||||
e.consume();
|
||||
});
|
||||
|
||||
NSLMainController controller = loader.getController();
|
||||
MediatorControl.INSTANCE.setHostServices(getHostServices());
|
||||
|
||||
controller.setHostServices(getHostServices());
|
||||
primaryStage.setOnHidden(e-> {
|
||||
AppPreferences.getInstance().setSceneHeight(mainScene.getHeight());
|
||||
AppPreferences.getInstance().setSceneWidth(mainScene.getWidth());
|
||||
|
@ -85,7 +83,6 @@ public class NSLMain extends Application {
|
|||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
NSLMain.appVersion = ResourceBundle.getBundle("app").getString("_version");
|
||||
if (args.length == 0) {
|
||||
launch(args);
|
||||
}
|
||||
|
|
71
src/main/java/nsusbloader/RainbowHexDump.java
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Debug tool like hexdump <3
|
||||
*/
|
||||
public class RainbowHexDump {
|
||||
private static final String ANSI_RESET = "\u001B[0m";
|
||||
private static final String ANSI_BLACK = "\u001B[30m";
|
||||
private static final String ANSI_RED = "\u001B[31m";
|
||||
private static final String ANSI_GREEN = "\u001B[32m";
|
||||
private static final String ANSI_YELLOW = "\u001B[33m";
|
||||
private static final String ANSI_BLUE = "\u001B[34m";
|
||||
private static final String ANSI_PURPLE = "\u001B[35m";
|
||||
private static final String ANSI_CYAN = "\u001B[36m";
|
||||
private static final String ANSI_WHITE = "\u001B[37m";
|
||||
|
||||
public static void hexDumpUTF8(byte[] byteArray){
|
||||
System.out.print(ANSI_BLUE);
|
||||
for (int i=0; i < byteArray.length; i++)
|
||||
System.out.printf("%02d-", i%100);
|
||||
System.out.println(">"+ANSI_RED+byteArray.length+ANSI_RESET);
|
||||
for (byte b: byteArray)
|
||||
System.out.printf("%02x ", b);
|
||||
System.out.println();
|
||||
System.out.print("\t\t\t"
|
||||
+ new String(byteArray, StandardCharsets.UTF_8)
|
||||
+ "\n");
|
||||
}
|
||||
|
||||
public static void hexDumpUTF8ForWin(byte[] byteArray){
|
||||
for (int i=0; i < byteArray.length; i++)
|
||||
System.out.printf("%02d-", i%100);
|
||||
System.out.println(">"+byteArray.length);
|
||||
for (byte b: byteArray)
|
||||
System.out.printf("%02x ", b);
|
||||
System.out.println();
|
||||
System.out.print(new String(byteArray, StandardCharsets.UTF_8)
|
||||
+ "\n");
|
||||
}
|
||||
|
||||
public static void hexDumpUTF16LE(byte[] byteArray){
|
||||
System.out.print(ANSI_BLUE);
|
||||
for (int i=0; i < byteArray.length; i++)
|
||||
System.out.printf("%02d-", i%100);
|
||||
System.out.println(">"+ANSI_RED+byteArray.length+ANSI_RESET);
|
||||
for (byte b: byteArray)
|
||||
System.out.printf("%02x ", b);
|
||||
System.out.print(new String(byteArray, StandardCharsets.UTF_16LE)
|
||||
+ "\n");
|
||||
}
|
||||
}
|
|
@ -44,6 +44,7 @@ public class ServiceWindow {
|
|||
alertBox.getDialogPane().setMinWidth(Region.USE_PREF_SIZE);
|
||||
alertBox.getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
|
||||
alertBox.setResizable(true); // Java bug workaround for JDR11/OpenJFX. TODO: nothing. really.
|
||||
alertBox.getDialogPane().getStylesheets().add(AppPreferences.getInstance().getTheme());
|
||||
|
||||
Stage dialogStage = (Stage) alertBox.getDialogPane().getScene().getWindow();
|
||||
dialogStage.setAlwaysOnTop(true);
|
||||
|
@ -53,9 +54,6 @@ public class ServiceWindow {
|
|||
new Image("/res/warn_ico64x64.png"),
|
||||
new Image("/res/warn_ico128x128.png")
|
||||
);
|
||||
alertBox.getDialogPane().getStylesheets().add(AppPreferences.getInstance().getTheme());
|
||||
dialogStage.getScene().getRoot().setStyle(AppPreferences.getInstance().getFontStyle());
|
||||
|
||||
alertBox.show();
|
||||
dialogStage.toFront();
|
||||
}
|
||||
|
@ -70,6 +68,7 @@ public class ServiceWindow {
|
|||
alertBox.getDialogPane().setMinWidth(Region.USE_PREF_SIZE);
|
||||
alertBox.getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
|
||||
alertBox.setResizable(true); // Java bug workaround for JDR11/OpenJFX. TODO: nothing. really.
|
||||
alertBox.getDialogPane().getStylesheets().add(AppPreferences.getInstance().getTheme());
|
||||
|
||||
Stage dialogStage = (Stage) alertBox.getDialogPane().getScene().getWindow();
|
||||
dialogStage.setAlwaysOnTop(true);
|
||||
|
@ -79,10 +78,6 @@ public class ServiceWindow {
|
|||
new Image("/res/ask_ico64x64.png"),
|
||||
new Image("/res/ask_ico128x128.png")
|
||||
);
|
||||
|
||||
alertBox.getDialogPane().getStylesheets().add(AppPreferences.getInstance().getTheme());
|
||||
dialogStage.getScene().getRoot().setStyle(AppPreferences.getInstance().getFontStyle());
|
||||
|
||||
dialogStage.toFront();
|
||||
|
||||
Optional<ButtonType> result = alertBox.showAndWait();
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader;
|
||||
|
||||
import nsusbloader.Controllers.ISubscriber;
|
||||
import nsusbloader.Controllers.Payload;
|
||||
import nsusbloader.NSLDataTypes.EModule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class TransfersPublisher {
|
||||
private final AtomicBoolean isTransferActive = new AtomicBoolean(false);
|
||||
|
||||
private final List<ISubscriber> subscribers = new ArrayList<>();
|
||||
|
||||
public TransfersPublisher(ISubscriber... subscriber){
|
||||
subscribers.addAll(Arrays.asList(subscriber));
|
||||
}
|
||||
|
||||
public void setTransferActive(EModule appModuleType, boolean isActive, Payload payload) {
|
||||
isTransferActive.set(isActive);
|
||||
subscribers.forEach(s->s.notify(appModuleType, isActive, payload));
|
||||
}
|
||||
|
||||
public boolean getTransferActive() {
|
||||
return isTransferActive.get();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2022 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -26,14 +26,16 @@ public class LocaleHolder {
|
|||
private final String localeCode;
|
||||
private final String languageName;
|
||||
|
||||
public LocaleHolder(Locale locale){
|
||||
this.locale = locale;
|
||||
this.localeCode = locale.toString();
|
||||
this.languageName = locale.getDisplayLanguage(locale) + " (" + locale + ")";
|
||||
}
|
||||
|
||||
public LocaleHolder(String localeFileName) {
|
||||
String language = localeFileName.substring(7, 9);
|
||||
String country;
|
||||
if (localeFileName.length() > 23) // ISO 639-3 not supported by Java
|
||||
country = localeFileName.substring(10, localeFileName.indexOf('.'));
|
||||
else // ISO 639-1
|
||||
country = localeFileName.substring(10, 12);
|
||||
this.locale = new Locale(language, country);
|
||||
String country = localeFileName.substring(7, 9);
|
||||
String language = localeFileName.substring(10, 12);
|
||||
this.locale = new Locale(country, language);
|
||||
this.localeCode = locale.toString();
|
||||
this.languageName = locale.getDisplayLanguage(locale) + " (" + locale + ")";
|
||||
}
|
||||
|
@ -45,7 +47,7 @@ public class LocaleHolder {
|
|||
|
||||
public String getLocaleCode(){
|
||||
return localeCode;
|
||||
}
|
||||
};
|
||||
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2023 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -25,8 +25,8 @@ import java.net.URL;
|
|||
|
||||
public class DownloadDriversTask extends Task<String> {
|
||||
|
||||
public static final long DRIVERS_FILE_SIZE = 3857375;
|
||||
private static final String driverFileLocationURL = "https://github.com/developersu/NS-Drivers/releases/download/v1.0/Drivers_set.exe";
|
||||
private static final long driversFileSize = 3857375;
|
||||
|
||||
private static File driversInstallerFile;
|
||||
|
||||
|
@ -38,7 +38,7 @@ public class DownloadDriversTask extends Task<String> {
|
|||
}
|
||||
|
||||
private boolean isDriversDownloaded(){
|
||||
return driversInstallerFile != null && driversInstallerFile.length() == DRIVERS_FILE_SIZE;
|
||||
return driversInstallerFile != null && driversInstallerFile.length() == driversFileSize;
|
||||
}
|
||||
|
||||
private boolean downloadDrivers(){
|
||||
|
@ -64,7 +64,7 @@ public class DownloadDriversTask extends Task<String> {
|
|||
while ((bytesRead = bis.read(dataBuffer, 0, 1024)) != -1) {
|
||||
fos.write(dataBuffer, 0, bytesRead);
|
||||
totalRead += bytesRead;
|
||||
updateProgress(totalRead, DRIVERS_FILE_SIZE);
|
||||
updateProgress(totalRead, driversFileSize);
|
||||
if (this.isCancelled()) {
|
||||
bis.close();
|
||||
fos.close();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2023 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -32,32 +32,19 @@ import javafx.scene.layout.VBox;
|
|||
import javafx.stage.Stage;
|
||||
import nsusbloader.AppPreferences;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class DriversInstall {
|
||||
|
||||
private static volatile boolean isRunning;
|
||||
|
||||
private final ResourceBundle resourceBundle;
|
||||
private Label runInstallerStatusLabel;
|
||||
|
||||
public DriversInstall(ResourceBundle rb){
|
||||
this.resourceBundle = rb;
|
||||
|
||||
if (isDriversDistributesWithExecutable())
|
||||
runInstaller("Drivers_set.exe");
|
||||
else
|
||||
runDownloadProcess();
|
||||
}
|
||||
|
||||
private boolean isDriversDistributesWithExecutable(){
|
||||
final File drivers = new File("Drivers_set.exe");
|
||||
|
||||
return drivers.length() == DownloadDriversTask.DRIVERS_FILE_SIZE;
|
||||
}
|
||||
|
||||
private void runDownloadProcess(){
|
||||
if (DriversInstall.isRunning)
|
||||
return;
|
||||
|
||||
|
@ -65,11 +52,11 @@ public class DriversInstall {
|
|||
|
||||
DownloadDriversTask downloadTask = new DownloadDriversTask();
|
||||
|
||||
Button cancelButton = new Button(resourceBundle.getString("btn_Cancel"));
|
||||
Button cancelButton = new Button(rb.getString("btn_Cancel"));
|
||||
|
||||
HBox hBoxInformation = new HBox();
|
||||
hBoxInformation.setAlignment(Pos.TOP_LEFT);
|
||||
hBoxInformation.getChildren().add(new Label(resourceBundle.getString("windowBodyDownloadDrivers")));
|
||||
hBoxInformation.getChildren().add(new Label(rb.getString("windowBodyDownloadDrivers")));
|
||||
|
||||
ProgressBar progressBar = new ProgressBar();
|
||||
progressBar.setPrefWidth(Double.MAX_VALUE);
|
||||
|
@ -106,7 +93,7 @@ public class DriversInstall {
|
|||
|
||||
Stage stage = new Stage();
|
||||
|
||||
stage.setTitle(resourceBundle.getString("windowTitleDownloadDrivers"));
|
||||
stage.setTitle(rb.getString("windowTitleDownloadDrivers"));
|
||||
stage.getIcons().addAll(
|
||||
new Image("/res/dwnload_ico32x32.png"), //TODO: REDRAW
|
||||
new Image("/res/dwnload_ico48x48.png"),
|
||||
|
@ -119,7 +106,6 @@ public class DriversInstall {
|
|||
Scene mainScene = new Scene(parentVBox, 405, 155);
|
||||
|
||||
mainScene.getStylesheets().add(AppPreferences.getInstance().getTheme());
|
||||
parentVBox.setStyle(AppPreferences.getInstance().getFontStyle());
|
||||
|
||||
stage.setOnHidden(windowEvent -> {
|
||||
downloadTask.cancel(true );
|
||||
|
@ -131,7 +117,7 @@ public class DriversInstall {
|
|||
stage.toFront();
|
||||
|
||||
downloadTask.setOnSucceeded(event -> {
|
||||
cancelButton.setText(resourceBundle.getString("btn_Close"));
|
||||
cancelButton.setText(rb.getString("btn_Close"));
|
||||
|
||||
String returnedValue = downloadTask.getValue();
|
||||
|
||||
|
@ -157,7 +143,7 @@ public class DriversInstall {
|
|||
return true;
|
||||
}
|
||||
catch (Exception e){
|
||||
runInstallerStatusLabel.setText("Error: "+e);
|
||||
runInstallerStatusLabel.setText("Error: "+e.toString());
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2022 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches;
|
||||
/**
|
||||
* Searches instructions (via known patterns) that follows 'specific instruction' we want to patch.
|
||||
* Returns offset of the pattern. Not offset of the 'specific instruction'.
|
||||
* */
|
||||
public abstract class AHeuristic {
|
||||
protected boolean isLDR(int expression){ return (expression >> 22 & 0x2FF) == 0x2e5; }// LDR ! Sounds like LDP, don't mess up
|
||||
protected boolean isLDP(int expression){ return (expression >> 22 & 0x1F9) == 0xA1; }// LDP !
|
||||
protected boolean isCBNZ(int expression){ return (expression >> 24 & 0x7f) == 0x35; }
|
||||
protected boolean isMOV(int expression){ return (expression >> 23 & 0xff) == 0xA5; }
|
||||
protected boolean isTBZ(int expression){ return (expression >> 24 & 0x7f) == 0x36; }
|
||||
protected boolean isLDRB_LDURB(int expression){ return (expression >> 21 & 0x7f7) == 0x1c2; }
|
||||
protected boolean isMOV_REG(int expression){ return (expression & 0x7FE0FFE0) == 0x2A0003E0; }
|
||||
protected boolean isB(int expression) { return (expression >> 26 & 0x3f) == 0x5; }
|
||||
protected boolean isBL(int expression){ return (expression >> 26 & 0x3f) == 0x25; }
|
||||
protected boolean isADD(int expression){ return (expression >> 23 & 0xff) == 0x22; }
|
||||
public abstract boolean isFound();
|
||||
public abstract boolean wantLessEntropy();
|
||||
public abstract int getOffset() throws Exception;
|
||||
public abstract String getDetails();
|
||||
|
||||
/**
|
||||
* Should be used if wantLessEntropy() == true
|
||||
* @return isFound();
|
||||
* */
|
||||
public abstract boolean setOffsetsNearby(int offsetNearby);
|
||||
}
|
|
@ -1,591 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2022 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import nsusbloader.NSLMain;
|
||||
|
||||
public class BinToAsmPrinter {
|
||||
static {
|
||||
boolean notWindows = ! System.getProperty("os.name").toLowerCase().contains("windows");
|
||||
|
||||
if(notWindows && NSLMain.isCli){
|
||||
ANSI_RESET = "\u001B[0m";
|
||||
ANSI_GREEN = "\u001B[32m";
|
||||
ANSI_BLUE = "\u001B[34m";
|
||||
ANSI_YELLOW = "\u001B[33m";
|
||||
ANSI_PURPLE = "\u001B[35m";
|
||||
ANSI_CYAN = "\u001B[36m";
|
||||
ANSI_RED = "\u001B[31m";
|
||||
}
|
||||
else {
|
||||
ANSI_RESET = ANSI_RED = ANSI_GREEN = ANSI_BLUE = ANSI_YELLOW = ANSI_PURPLE = ANSI_CYAN = "";
|
||||
}
|
||||
}
|
||||
private static final String ANSI_RESET;
|
||||
private static final String ANSI_RED;
|
||||
private static final String ANSI_GREEN;
|
||||
private static final String ANSI_BLUE;
|
||||
private static final String ANSI_YELLOW;
|
||||
private static final String ANSI_PURPLE;
|
||||
private static final String ANSI_CYAN;
|
||||
|
||||
public static String print(int instructionExpression, int offset){
|
||||
if (instructionExpression == 0xd503201f)
|
||||
return printNOP(instructionExpression);
|
||||
|
||||
if ((instructionExpression & 0x7FE0FFE0) == 0x2A0003E0) {
|
||||
return printMOVRegister(instructionExpression);
|
||||
}
|
||||
|
||||
switch ((instructionExpression >> 23 & 0b011111111)){
|
||||
case 0xA5:
|
||||
return printMOV(instructionExpression);
|
||||
case 0x62:
|
||||
if (((instructionExpression & 0x1f) == 0x1f)){
|
||||
return printCMN(instructionExpression);
|
||||
}
|
||||
}
|
||||
|
||||
switch (instructionExpression >> 24 & 0xff) {
|
||||
case 0x34:
|
||||
case 0xb4:
|
||||
return printCBZ(instructionExpression, offset);
|
||||
case 0xb5:
|
||||
case 0x35:
|
||||
return printCBNZ(instructionExpression, offset);
|
||||
case 0x36:
|
||||
case 0xb6:
|
||||
return printTBZ(instructionExpression, offset);
|
||||
case 0x54:
|
||||
return printBConditional(instructionExpression, offset);
|
||||
}
|
||||
switch ((instructionExpression >> 26 & 0b111111)) {
|
||||
case 0x5:
|
||||
return printB(instructionExpression, offset);
|
||||
case 0x25:
|
||||
return printBL(instructionExpression, offset);
|
||||
}
|
||||
|
||||
return printUnknown(instructionExpression);
|
||||
}
|
||||
public static String printSimplified(int instructionExpression, int offset){
|
||||
if (instructionExpression == 0xd503201f)
|
||||
return printNOPSimplified(instructionExpression, offset);
|
||||
|
||||
if ((instructionExpression & 0x7FE0FFE0) == 0x2A0003E0) {
|
||||
return printMOVRegisterSimplified(instructionExpression, offset);
|
||||
}
|
||||
|
||||
switch (instructionExpression >> 22 & 0b1011111111) {
|
||||
case 0x2e5:
|
||||
return printLRDImmUnsignSimplified(instructionExpression, offset);
|
||||
case 0xe5:
|
||||
return printLRDBImmUnsignSimplified(instructionExpression, offset);
|
||||
}
|
||||
|
||||
if ((instructionExpression >> 21 & 0x7FF) == 0x1C2)
|
||||
return printImTooLazy("LDURB", instructionExpression, offset);
|
||||
|
||||
// same to (afterJumpExpression >> 23 & 0x1F9) != 0xA1
|
||||
switch (instructionExpression >> 22 & 0x1FF){
|
||||
case 0xA3: // 0b10100011
|
||||
case 0xA7: // 0b10100111
|
||||
case 0xA5: // 0b10100101
|
||||
return printImTooLazy("LDP", instructionExpression, offset);
|
||||
}
|
||||
|
||||
switch ((instructionExpression >> 23 & 0x1ff)){
|
||||
case 0xA5:
|
||||
return printMOVSimplified(instructionExpression, offset);
|
||||
case 0x22:
|
||||
return printImTooLazy("ADD", instructionExpression, offset);
|
||||
case 0x62:
|
||||
if (((instructionExpression & 0x1f) == 0x1f)){
|
||||
return printCMNSimplified(instructionExpression, offset);
|
||||
}
|
||||
case 0xA2:
|
||||
return printSUBSimplified(instructionExpression, offset);
|
||||
case 0xE2:
|
||||
case 0x1e2:
|
||||
return printCMPSimplified(instructionExpression, offset);
|
||||
case 0x24:
|
||||
case 0x124:
|
||||
return printANDSimplified(instructionExpression, offset);
|
||||
}
|
||||
|
||||
switch (instructionExpression >> 24 & 0xff) {
|
||||
case 0x34:
|
||||
case 0xb4:
|
||||
return printCBZSimplified(instructionExpression, offset);
|
||||
case 0xb5:
|
||||
case 0x35:
|
||||
return printCBNZSimplified(instructionExpression, offset);
|
||||
case 0x36:
|
||||
case 0xb6:
|
||||
return printTBZSimplified(instructionExpression, offset);
|
||||
case 0x54:
|
||||
return printBConditionalSimplified(instructionExpression, offset);
|
||||
case 0xeb:
|
||||
case 0x6b:
|
||||
if ((instructionExpression & 0x1f) == 0b11111)
|
||||
return printCMPShiftedRegisterSimplified(instructionExpression, offset);
|
||||
}
|
||||
|
||||
switch (instructionExpression >> 26 & 0b111111) {
|
||||
case 0x5:
|
||||
return printBSimplified(instructionExpression, offset);
|
||||
case 0x25:
|
||||
return printBLSimplified(instructionExpression, offset);
|
||||
}
|
||||
|
||||
if ((instructionExpression >> 10 & 0x3FFFFF) == 0x3597c0 && ((instructionExpression & 0x1F) == 0))
|
||||
return printRetSimplified(instructionExpression, offset);
|
||||
return printUnknownSimplified(instructionExpression, offset);
|
||||
}
|
||||
|
||||
private static String printCBZ(int instructionExpression, int offset){
|
||||
int conditionalJumpLocation = ((instructionExpression >> 5 & 0x7FFFF) * 4 + offset) & 0xfffff;
|
||||
|
||||
return String.format(ANSI_YELLOW + "sf == 0 ? <Wt> else <Xt>\n" +
|
||||
"CBZ <?t>, <label> |.....CBZ signature......|\n" +
|
||||
ANSI_CYAN + " sf 0 1 1 0 1 0 0 |imm19..........................................................||Rd.............|" + ANSI_RESET + "\n" +
|
||||
ANSI_GREEN +" 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 " + ANSI_RESET + "\n" +
|
||||
"Instruction (BE) : %s | %s\n\n"+
|
||||
ANSI_YELLOW + "CBZ " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "#0x%x" + ANSI_RESET + " (Real: " + ANSI_BLUE + "#0x%x" + ANSI_RESET + ")\n",
|
||||
intAsBinString(instructionExpression), intAsHexString(instructionExpression),
|
||||
(instructionExpression >> 31 == 0) ? "w" : "x", (instructionExpression & 0b11111),
|
||||
conditionalJumpLocation, (conditionalJumpLocation + 0x100));
|
||||
}
|
||||
|
||||
|
||||
private static String printCBNZ(int instructionExpression, int offset){
|
||||
int conditionalJumpLocation = ((instructionExpression >> 5 & 0x7FFFF) * 4 + offset) & 0xfffff;
|
||||
|
||||
return String.format(ANSI_YELLOW + "sf == 0 ? <Wt> else <Xt>\n" +
|
||||
"CBNZ <?t>, <label> |.....CBZ signature......|\n" +
|
||||
ANSI_CYAN + " sf 0 1 1 0 1 0 |imm19..........................................................||Rd.............|" + ANSI_RESET + "\n" +
|
||||
ANSI_GREEN +" 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 " + ANSI_RESET + "\n" +
|
||||
"Instruction (BE) : %s | %s\n\n"+
|
||||
ANSI_YELLOW + "CBNZ " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "#0x%x" + ANSI_RESET + " (Real: " + ANSI_BLUE + "#0x%x" + ANSI_RESET + ")\n",
|
||||
intAsBinString(instructionExpression), intAsHexString(instructionExpression),
|
||||
(instructionExpression >> 31 == 0) ? "w" : "x", (instructionExpression & 0b11111),
|
||||
conditionalJumpLocation, (conditionalJumpLocation + 0x100));
|
||||
}
|
||||
|
||||
private static String printCMN(int instructionExpression){
|
||||
int Rn = instructionExpression >> 5 & 0x1F;
|
||||
int imm = instructionExpression >> 10 & 0xFFF;
|
||||
|
||||
return String.format(ANSI_YELLOW + "sf == 0 ? <Wt> else <Xt>\n" +
|
||||
"CMN <?n>, <label> |.....CMN signature...........| |..CMN signature.|\n" +
|
||||
ANSI_CYAN+" sf 0 1 1 0 0 0 1 0 |imm12......................................||Rn.............| 1 1 1 1 1" + ANSI_RESET + "\n" +
|
||||
ANSI_GREEN +" 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 " + ANSI_RESET + "\n" +
|
||||
"Instruction (BE) : %s | %s\n\n" +
|
||||
ANSI_YELLOW + "CMN " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "#0x%x" + ANSI_RESET + "\n",
|
||||
intAsBinString(instructionExpression), intAsHexString(instructionExpression),
|
||||
(instructionExpression >> 31 == 0) ? "w" : "x", Rn, imm);
|
||||
}
|
||||
|
||||
private static String printB(int instructionExpression, int offset){
|
||||
int conditionalJumpLocationPatch = ((instructionExpression & 0x3ffffff) * 4 + offset) & 0xfffff;
|
||||
|
||||
return String.format(ANSI_YELLOW+"B <label> |....B signature...|\n" +
|
||||
" "+ANSI_CYAN+" 0 0 0 1 0 1 |imm26...................................................................................|" + ANSI_RESET + "\n" +
|
||||
ANSI_GREEN +" 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 " + ANSI_RESET + "\n" +
|
||||
"Instruction (BE) : %s | %s\n" +
|
||||
ANSI_YELLOW + "%s " + ANSI_BLUE + "#0x%x" + ANSI_RESET + " (Real: " + ANSI_BLUE + "#0x%x" + ANSI_RESET + ")\n",
|
||||
intAsBinString(instructionExpression), intAsHexString(instructionExpression),
|
||||
((instructionExpression >> 26 & 0b111111) == 5)?"B":"Some weird stuff",
|
||||
conditionalJumpLocationPatch, (conditionalJumpLocationPatch + 0x100));
|
||||
}
|
||||
|
||||
|
||||
private static String printBL(int instructionExpression, int offset){
|
||||
int conditionalJumpLocationPatch = ((instructionExpression & 0x3ffffff) * 4 + offset) & 0xfffff;
|
||||
|
||||
return String.format(ANSI_YELLOW+"BL <label> |...BL signature...|\n" +
|
||||
" "+ANSI_CYAN+" 1 0 0 1 0 1 |imm26...................................................................................|" + ANSI_RESET + "\n" +
|
||||
ANSI_GREEN +" 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 " + ANSI_RESET + "\n" +
|
||||
"Instruction (BE) : %s | %s\n" +
|
||||
ANSI_YELLOW + "%s " + ANSI_BLUE + "#0x%x" + ANSI_RESET + " (Real: " + ANSI_BLUE + "#0x%x" + ANSI_RESET + ")\n",
|
||||
intAsBinString(instructionExpression), intAsHexString(instructionExpression),
|
||||
((instructionExpression >> 26 & 0b111111) == 25)?"BL":"Some weird stuff",
|
||||
conditionalJumpLocationPatch, (conditionalJumpLocationPatch + 0x100));
|
||||
}
|
||||
|
||||
|
||||
private static String printMOV(int instructionExpression){
|
||||
int imm16 = instructionExpression >> 5 & 0xFFFF;
|
||||
int sfHw = (instructionExpression >> 22 & 1);
|
||||
|
||||
return String.format(ANSI_YELLOW + "sf == 0 && hw == 0x ? <Wt> else <Xt>\n" +
|
||||
"MOV <?t>, <label> |.....MOV signature...........|\n" +
|
||||
ANSI_CYAN +" sf 1 0 1 0 0 1 0 1 |hw...|imm16.................................................||Rd.............|" + ANSI_RESET + "\n" +
|
||||
ANSI_GREEN +" 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 " + ANSI_RESET + "\n" +
|
||||
"Instruction (BE) : %s | %s\n" +
|
||||
ANSI_YELLOW + "MOV " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "#0x%x" + ANSI_RESET + "\n",
|
||||
intAsBinString(instructionExpression), intAsHexString(instructionExpression),
|
||||
(sfHw == 0) ? "w" : "x", (instructionExpression & 0b11111), imm16);
|
||||
}
|
||||
|
||||
private static String printMOVRegister(int instructionExpression){
|
||||
String sfHw = (instructionExpression >> 31 & 1) == 0 ? "W" : "X";
|
||||
int Rm = instructionExpression >> 16 & 0xF;
|
||||
int Rd = instructionExpression & 0xF;
|
||||
|
||||
return String.format(ANSI_YELLOW + "sf == 0 && hw == 0x ? <Wt> else <Xt>\n" +
|
||||
"MOV (register) <?d>, <?m> |.....MOV (register) signature.......|\n" +
|
||||
ANSI_CYAN +" sf 0 1 0 1 0 1 0 0 0 0 |Rm..............| 0 0 0 0 0 0 1 1 1 1 1 |Rd.............|" + ANSI_RESET + "\n" +
|
||||
ANSI_GREEN +" 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 " + ANSI_RESET + "\n" +
|
||||
"Instruction (BE) : %s | %s\n" +
|
||||
ANSI_YELLOW + "MOV(reg) " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "%s%d" + ANSI_RESET + "\n",
|
||||
intAsBinString(instructionExpression), intAsHexString(instructionExpression),
|
||||
sfHw, Rm, sfHw, Rd);
|
||||
}
|
||||
|
||||
private static String printNOP(int instructionExpression){
|
||||
return String.format(
|
||||
ANSI_YELLOW+"NOP |.....NOP signature..........................................................................................|\n" +
|
||||
ANSI_CYAN +" 1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 1 " + ANSI_RESET + "\n" +
|
||||
ANSI_GREEN +" 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 " + ANSI_RESET + "\n"+
|
||||
"Instruction (BE) : %s | %s\n" +
|
||||
ANSI_YELLOW + "%s" + ANSI_RESET + "\n",
|
||||
intAsBinString(instructionExpression), intAsHexString(instructionExpression),
|
||||
(instructionExpression == 0xd503201f)?"NOP":"Some weird stuff");
|
||||
}
|
||||
|
||||
private static String printTBZ(int instructionExpression, int offset){
|
||||
int xwSelector = (instructionExpression >> 31 & 1);
|
||||
int imm = instructionExpression >> 18 & 0b11111;
|
||||
int Rt = instructionExpression & 0b11111;
|
||||
int label = (offset + (instructionExpression >> 5 & 0x3fff) * 4) & 0xfffff;
|
||||
|
||||
return String.format(ANSI_YELLOW + "sf == 0 && hw == 0x ? <Wt> else <Xt>\n" +
|
||||
"TBZ <?t>,#<imm>, <label> |.....TBZ signature.......|\n" +
|
||||
ANSI_CYAN+" b5 0 1 1 0 1 1 0 |b40.............|imm14.........................................||Rt.............|" + ANSI_RESET + "\n" +
|
||||
ANSI_GREEN +" 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 " + ANSI_RESET + "\n" +
|
||||
"Instruction (BE) : %s | %s\n" +
|
||||
ANSI_YELLOW + "TBZ " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "#0x%x" + ANSI_RESET + ", " + ANSI_PURPLE + "%x" + ANSI_RESET + "\n",
|
||||
intAsBinString(instructionExpression), intAsHexString(instructionExpression),
|
||||
(xwSelector == 0) ? "w" : "x", Rt, imm, label);
|
||||
}
|
||||
|
||||
private static String printBConditional(int instructionExpression, int offset){
|
||||
int conditionalJumpLocation = ((instructionExpression >> 4 & 0b1111111111111111111) * 4 + offset) & 0xfffff;
|
||||
|
||||
return String.format(
|
||||
ANSI_YELLOW+"B.%s <label> |...B.cond signature.......|\n" +
|
||||
ANSI_CYAN+" 0 1 0 1 0 1 0 0 |imm19..........................................................| 0 |.condit...|" + ANSI_RESET + "\n" +
|
||||
ANSI_GREEN +" 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 " + ANSI_RESET + "\n" +
|
||||
"Instruction (BE) : %s | %s\n" +
|
||||
ANSI_YELLOW + "B.%s " + ANSI_BLUE + "#0x%x" + ANSI_RESET + " (Real: " + ANSI_BLUE + "#0x%x" + ANSI_RESET + ")\n",
|
||||
getBConditionalMarker(instructionExpression & 0xf),
|
||||
intAsBinString(instructionExpression), intAsHexString(instructionExpression),
|
||||
getBConditionalMarker(instructionExpression & 0xf),
|
||||
conditionalJumpLocation, (conditionalJumpLocation + 0x100));
|
||||
}
|
||||
|
||||
private static String printUnknown(int instructionExpression){
|
||||
return String.format(ANSI_RED + " 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 " + ANSI_RESET + "\n" +
|
||||
"Instruction (BE) : %s | %s\n",
|
||||
intAsBinString(instructionExpression), intAsHexString(instructionExpression));
|
||||
}
|
||||
|
||||
private static String getBConditionalMarker(int cond){
|
||||
switch (cond){
|
||||
case 0b0000: return "EQ";
|
||||
case 0b0001: return "NE";
|
||||
case 0b0010: return "CS";
|
||||
case 0b0011: return "CC";
|
||||
case 0b0100: return "MI";
|
||||
case 0b0101: return "PL";
|
||||
case 0b0110: return "VS";
|
||||
case 0b0111: return "VC";
|
||||
case 0b1000: return "HI";
|
||||
case 0b1001: return "LS";
|
||||
case 0b1010: return "GE";
|
||||
case 0b1011: return "LT";
|
||||
case 0b1100: return "GT";
|
||||
case 0b1101: return "LE";
|
||||
case 0b1110: return "AL";
|
||||
default: return "??";
|
||||
}
|
||||
/*
|
||||
"__________________CheatSheet_____________________________________\n"+
|
||||
"0000 | EQ | Z set | equal\n"+
|
||||
"0001 | NE | Z clear | not equal\n"+
|
||||
"0010 | CS | C set | unsigned higher or same\n"+
|
||||
"0011 | CC | C clear | unsigned lower\n"+
|
||||
"0100 | MI | N set | negative\n"+
|
||||
"0101 | PL | N clear | positive or zero\n"+
|
||||
"0110 | VS | V set | overflow\n"+
|
||||
"0111 | VC | V clear | no overflow\n"+
|
||||
"1000 | HI | C set & V clear | unsigned higher\n"+
|
||||
"1001 | LS | C clear or Z set | unsigned lower or same\n"+
|
||||
"1010 | GE | N equals V | greater or equal\n"+
|
||||
"1011 | LT | N not equals V | less than\n"+
|
||||
"1100 | GT | Z clear AND (N equals V) | greater that\n"+
|
||||
"1101 | LE | Z set OR (N not equals V) | less than or equal\n"+
|
||||
"1110 | AL | (ignored) | always\n";
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
private static String printCBZSimplified(int instructionExpression, int offset){
|
||||
int conditionalJumpLocation = ((instructionExpression >> 5 & 0x7FFFF) * 4 + offset) & 0xfffff;
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " CBZ " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "#0x%x" + ANSI_RESET + " (" + ANSI_BLUE + "#0x%x" + ANSI_RESET + ")\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
(instructionExpression >> 31 == 0) ? "w" : "x", (instructionExpression & 0b11111),
|
||||
conditionalJumpLocation, (conditionalJumpLocation + 0x100));
|
||||
}
|
||||
|
||||
private static String printCBNZSimplified(int instructionExpression, int offset){
|
||||
int conditionalJumpLocation = ((instructionExpression >> 5 & 0x7FFFF) * 4 + offset) & 0xfffff;
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " CBNZ " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "#0x%x" + ANSI_RESET + " (" + ANSI_BLUE + "#0x%x" + ANSI_RESET + ")\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
(instructionExpression >> 31 == 0) ? "w" : "x", (instructionExpression & 0b11111),
|
||||
conditionalJumpLocation, (conditionalJumpLocation + 0x100));
|
||||
}
|
||||
|
||||
private static String printBSimplified(int instructionExpression, int offset){
|
||||
int conditionalJumpLocationPatch = ((instructionExpression & 0x3ffffff) * 4 + offset) & 0xfffff;
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " B " + ANSI_BLUE + "#0x%x" + ANSI_RESET + " (Real: " + ANSI_BLUE + "#0x%x" + ANSI_RESET + ")\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
conditionalJumpLocationPatch, (conditionalJumpLocationPatch + 0x100));
|
||||
}
|
||||
|
||||
|
||||
private static String printBLSimplified(int instructionExpression, int offset){
|
||||
int conditionalJumpLocationPatch = ((instructionExpression & 0x3ffffff) * 4 + offset) & 0xfffff;
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " BL " + ANSI_BLUE + "#0x%x" + ANSI_RESET + " (Real: " + ANSI_BLUE + "#0x%x" + ANSI_RESET + ")\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
conditionalJumpLocationPatch, (conditionalJumpLocationPatch + 0x100));
|
||||
}
|
||||
|
||||
private static String printMOVSimplified(int instructionExpression, int offset){
|
||||
int imm16 = instructionExpression >> 5 & 0xFFFF;
|
||||
int sfHw = (instructionExpression >> 22 & 1);
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " MOV " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "#0x%x" + ANSI_RESET + "\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
(sfHw == 0) ? "w" : "x", (instructionExpression & 0b11111), imm16);
|
||||
}
|
||||
|
||||
private static String printNOPSimplified(int instructionExpression, int offset){
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " NOP " + ANSI_RESET + "\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression);
|
||||
}
|
||||
|
||||
private static String printTBZSimplified(int instructionExpression, int offset){
|
||||
int xwSelector = (instructionExpression >> 31 & 1);
|
||||
int imm = instructionExpression >> 18 & 0b11111;
|
||||
int Rt = instructionExpression & 0b11111;
|
||||
int label = offset + (instructionExpression >> 5 & 0x3fff) * 4;
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " TBZ " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "#0x%x" + ANSI_RESET + ", " + ANSI_PURPLE + "%x" + ANSI_RESET + "\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
(xwSelector == 0) ? "w" : "x", Rt, imm, label);
|
||||
}
|
||||
|
||||
private static String printBConditionalSimplified(int instructionExpression, int offset){
|
||||
int conditionalJumpLocation = ((instructionExpression >> 4 & 0b1111111111111111111) * 4 + offset) & 0xfffff;
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " B.%s " + ANSI_BLUE + "#0x%x" + ANSI_RESET + " (Real: " + ANSI_BLUE + "#0x%x" + ANSI_RESET + ")\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
getBConditionalMarker(instructionExpression & 0xf),
|
||||
conditionalJumpLocation, (conditionalJumpLocation + 0x100));
|
||||
}
|
||||
private static String printImTooLazy(String name, int instructionExpression, int offset){
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " "+name+" . . . \n"+ ANSI_RESET,
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression);
|
||||
}
|
||||
|
||||
private static String printSUBSimplified(int instructionExpression, int offset){
|
||||
String wx = (instructionExpression >> 31 == 0) ? "W" : "X";
|
||||
int Rt = instructionExpression & 0x1f;
|
||||
int Rn = instructionExpression >> 5 & 0x1F;
|
||||
int imm12 = instructionExpression >> 10 & 0xFFF; // unsigned only
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " SUB (imm) " + ANSI_GREEN + "%s%d, " + ANSI_BLUE + "%s%d, #0x%x" + ANSI_RESET + "\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
wx, Rt, wx, Rn, imm12);
|
||||
}
|
||||
|
||||
private static String printMOVRegisterSimplified(int instructionExpression, int offset){ //ADD (immediate)
|
||||
String sfHw = (instructionExpression >> 31 & 1) == 0 ? "W" : "X";
|
||||
int Rm = instructionExpression >> 16 & 0x1F;
|
||||
int Rd = instructionExpression & 0x1F;
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " MOV (reg) " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "%s%d" + ANSI_RESET + "\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
sfHw, Rm, sfHw, Rd);
|
||||
}
|
||||
|
||||
private static String printCMNSimplified(int instructionExpression, int offset){
|
||||
int Rn = instructionExpression >> 5 & 0x1F;
|
||||
int imm = instructionExpression >> 10 & 0xFFF;
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " CMN " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "#0x%x" + ANSI_RESET + "\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
(instructionExpression >> 31 == 0) ? "w" : "x", Rn, imm);
|
||||
}
|
||||
|
||||
private static String printLRDImmUnsignSimplified(int instructionExpression, int offset){
|
||||
String wx = (instructionExpression >> 31 == 0) ? "W" : "X";
|
||||
int Rt = instructionExpression & 0x1f;
|
||||
int Rn = instructionExpression >> 5 & 0xF;
|
||||
int imm12 = (instructionExpression >> 10 & 0xFFF) * 8; // unsigned only
|
||||
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " LDR(imm) " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "[%s%d, #0x%x]" + ANSI_RESET + " (note: unsigned offset)\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
wx, Rt, wx, Rn, imm12);
|
||||
}
|
||||
private static String printLRDBImmUnsignSimplified(int instructionExpression, int offset){
|
||||
String wx = (instructionExpression >> 31 == 0) ? "W" : "X";
|
||||
int Rt = instructionExpression & 0x1f;
|
||||
int Rn = instructionExpression >> 5 & 0xF;
|
||||
int imm12 = (instructionExpression >> 10 & 0xFFF) * 8; // unsigned only
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " LDRB(imm) " + ANSI_GREEN + "%s%d " + ANSI_BLUE + "[%s%d, #0x%x]" + ANSI_RESET + " (note: unsigned offset)\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
wx, Rt, wx, Rn, imm12);
|
||||
}
|
||||
|
||||
private static String printCMPSimplified(int instructionExpression, int offset){
|
||||
String sf = (instructionExpression >> 31 == 0) ? "W" : "X";
|
||||
int Rn = instructionExpression >> 5 & 0x1F;
|
||||
int conditionalJumpLocation = (instructionExpression >> 10) & 0xfff;
|
||||
int LSL = (instructionExpression >> 22 & 0b1) == 1 ? 12 : 0;
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " CMP " + ANSI_GREEN + sf + "%d," +
|
||||
ANSI_BLUE + "0x%x" + ANSI_RESET + " (Real: " + ANSI_BLUE + "#0x%x" + ANSI_RESET + ") " + ANSI_PURPLE + "LSL #%d" + ANSI_RESET + "\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
Rn,
|
||||
conditionalJumpLocation, (conditionalJumpLocation + 0x100),
|
||||
LSL);
|
||||
}
|
||||
|
||||
private static String printCMPShiftedRegisterSimplified(int instructionExpression, int offset){
|
||||
String sf = (instructionExpression >> 31 == 0) ? "W" : "X";
|
||||
int Rn = instructionExpression >> 5 & 0x1F;
|
||||
int Rm = instructionExpression >> 16 & 0x1F;
|
||||
int imm6 = instructionExpression >> 10 & 0x3f;
|
||||
int LSL = (instructionExpression >> 22 & 0b11);
|
||||
String LSLStr;
|
||||
switch (LSL){
|
||||
case 0b00:
|
||||
LSLStr = "LSL";
|
||||
break;
|
||||
case 0b01:
|
||||
LSLStr = "LSR";
|
||||
break;
|
||||
case 0b10:
|
||||
LSLStr = "ASR";
|
||||
break;
|
||||
case 0b11:
|
||||
LSLStr = "RESERVED";
|
||||
break;
|
||||
default:
|
||||
LSLStr = "?";
|
||||
}
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " CMP (sr) " + ANSI_GREEN + sf + "%d," +
|
||||
ANSI_BLUE + sf + "%d " + ANSI_BLUE + LSLStr + ANSI_PURPLE + " %d" + ANSI_RESET + "\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression,
|
||||
Rn, Rm, imm6);
|
||||
}
|
||||
|
||||
private static String printANDSimplified(int instructionExpression, int offset){
|
||||
String sf = (instructionExpression >> 31 == 0) ? "W" : "X";
|
||||
int Rn = instructionExpression & 0x1F;
|
||||
int Rd = instructionExpression >> 5 & 0x1F;
|
||||
int imm;
|
||||
if (sf.equals("W"))
|
||||
imm = instructionExpression >> 10 & 0xfff;
|
||||
else
|
||||
imm = instructionExpression >> 10 & 0x1fff;
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " AND " + ANSI_GREEN + sf + "%d, " + ANSI_BLUE +
|
||||
sf + "%d" + ANSI_PURPLE + " # ??? 0b%s " + ANSI_RESET + "\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression, Rn, Rd, Converter.intToBinaryString(imm));
|
||||
}
|
||||
|
||||
private static String printRetSimplified(int instructionExpression, int offset){
|
||||
int Xn = (instructionExpression >> 5) & 0x1F;
|
||||
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " RET " + ANSI_GREEN + " X%d" + ANSI_RESET + "\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression, Xn == 0 ? 30 : Xn);
|
||||
}
|
||||
|
||||
private static String printUnknownSimplified(int instructionExpression, int offset){
|
||||
return String.format(
|
||||
"%05x "+ANSI_CYAN+"%08x (%08x)"+ANSI_YELLOW + " ??? 0b"+ANSI_RESET+ Converter.intToBinaryString(instructionExpression) +"\n",
|
||||
offset, Integer.reverseBytes(instructionExpression), instructionExpression);
|
||||
}
|
||||
|
||||
private static String intAsBinString(int number) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for(int i = 31; i >= 0 ; i--) {
|
||||
int mask = 1 << i;
|
||||
result.append((number & mask) != 0 ? "1" : "0");
|
||||
result.append(" ");
|
||||
if (i % 4 == 0)
|
||||
result.append(" ");
|
||||
}
|
||||
result.replace(result.length() - 1, result.length(), "");
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
private static String intAsHexString(int number) {
|
||||
number = Integer.reverseBytes(number);
|
||||
StringBuilder result = new StringBuilder();
|
||||
for(int i = 0; i <= 3 ; i++) {
|
||||
int mask = 0xff << i*8;
|
||||
result.append(String.format("%02x", (byte)((number & mask) >> i*8)));
|
||||
result.append(" ");
|
||||
}
|
||||
result.replace(result.length() - 1, result.length(), "");
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
Copyright 2019-2023 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches;
|
||||
|
||||
public class MalformedIniFileException extends Exception{
|
||||
public MalformedIniFileException(){}
|
||||
public MalformedIniFileException(String message){
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -1,161 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2022 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SimplyFind {
|
||||
private String what;
|
||||
private final byte[] where;
|
||||
|
||||
private Matcher matcherHex;
|
||||
private Matcher matcherDot;
|
||||
|
||||
private final List<Integer> findings = new ArrayList<>();
|
||||
private final int statementLength;
|
||||
private final List<SearchBlock> searchBlocks = new ArrayList<>();
|
||||
/**
|
||||
* Abstraction layer for searching patterns like "..CAFE..BE" in bytes array.
|
||||
* It's 'String' combination of hex values and '.' which stands for unknown value.
|
||||
* Returns offset of the first symbol.
|
||||
* */
|
||||
public SimplyFind(String what, byte[] where){
|
||||
this.where = where;
|
||||
if (! what.contains(".")){
|
||||
doKMPSearch(Converter.hexStringToByteArray(what), 0);
|
||||
this.statementLength = what.length()/2;
|
||||
return;
|
||||
}
|
||||
this.what = what.replaceAll("\\.", "\\.\\.");
|
||||
this.statementLength = this.what.length()/2;
|
||||
|
||||
buildSearchingSequence();
|
||||
complexSearch();
|
||||
}
|
||||
private void buildSearchingSequence(){
|
||||
Pattern patternHex = Pattern.compile("[0-9]|[A-F]|[a-f]");
|
||||
Pattern patternDot = Pattern.compile("\\.");
|
||||
this.matcherHex = patternHex.matcher(what);
|
||||
this.matcherDot = patternDot.matcher(what);
|
||||
|
||||
int nextDotPos = 0;
|
||||
int nextHexPos;
|
||||
|
||||
while(true){
|
||||
nextHexPos = getNextNumberPosition(nextDotPos);
|
||||
if (nextHexPos == -1)
|
||||
break;
|
||||
|
||||
nextDotPos = getNextDotPosition(nextHexPos);
|
||||
if (nextDotPos == -1) {
|
||||
searchBlocks.add(new SearchBlock(what.substring(nextHexPos), nextHexPos));
|
||||
break;
|
||||
}
|
||||
String searchStatement = what.substring(nextHexPos, nextDotPos);
|
||||
searchBlocks.add(new SearchBlock(searchStatement, nextHexPos));
|
||||
}
|
||||
}
|
||||
private int getNextNumberPosition(int since){
|
||||
if (matcherHex.find(since))
|
||||
return matcherHex.start();
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int getNextDotPosition(int since){
|
||||
if (matcherDot.find(since))
|
||||
return matcherDot.start();
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void complexSearch(){
|
||||
SearchBlock block = searchBlocks.get(0);
|
||||
doKMPSearch(block.statement, block.offsetInStatement);
|
||||
findings.removeIf(this::searchForward);
|
||||
}
|
||||
private boolean searchForward(int offset){
|
||||
for (int i = 1; i < searchBlocks.size(); i++) {
|
||||
SearchBlock block = searchBlocks.get(i);
|
||||
if (! doDumbSearch(block.statement, offset+block.offsetInStatement)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void doKMPSearch(byte[] subject, int skip){
|
||||
int whereSize = where.length;
|
||||
int subjectSize = subject.length;
|
||||
|
||||
int[] pf = new int[subjectSize];
|
||||
|
||||
int j = 0;
|
||||
for (int i = 1; i < subjectSize; i++ ) {
|
||||
while ((j > 0) && (subject[j] != subject[i]))
|
||||
j = pf[j-1];
|
||||
if (subject[j] == subject[i])
|
||||
j++;
|
||||
pf[i] = j;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for (int i = 0; i < whereSize; i++){
|
||||
while ((j > 0) && (subject[j] != where[i]))
|
||||
j = pf[j - 1];
|
||||
if (subject[j] == where[i])
|
||||
j++;
|
||||
if (j == subjectSize) {
|
||||
findings.add(i-j+1-skip);
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doDumbSearch(byte[] subject, int since){
|
||||
for (int i = 0; i < subject.length; i++) {
|
||||
if (where[since + i] != subject[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getStatementLength() {
|
||||
return statementLength;
|
||||
}
|
||||
|
||||
public List<Integer> getResults(){
|
||||
return findings;
|
||||
}
|
||||
|
||||
private static class SearchBlock{
|
||||
byte[] statement;
|
||||
int offsetInStatement;
|
||||
|
||||
SearchBlock(String statement, int offset){
|
||||
if (statement != null) {
|
||||
this.statement = Converter.hexStringToByteArray(statement);
|
||||
}
|
||||
this.offsetInStatement = offset/2;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2022 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.es;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import libKonogonka.fs.NCA.NCAProvider;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
class EsNcaSearchTask implements Callable<NCAProvider> {
|
||||
private final List<NCAProvider> ncaProviders;
|
||||
|
||||
EsNcaSearchTask(List<NCAProvider> ncaProviders){
|
||||
this.ncaProviders = ncaProviders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NCAProvider call() {
|
||||
try {
|
||||
for (NCAProvider ncaProvider : ncaProviders) {
|
||||
String titleId = Converter.byteArrToHexStringAsLE(ncaProvider.getTitleId());
|
||||
if (titleId.startsWith("0100000000000033") && ncaProvider.getContentType() == 0) {
|
||||
return ncaProvider;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,181 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2022 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
---
|
||||
Based on ES-AutoIPS.py patch script made by GBATemp member MrDude.
|
||||
Taken from: https://gbatemp.net/threads/info-on-sha-256-hashes-on-fs-patches.581550/
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.es;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import libKonogonka.fs.NCA.NCAProvider;
|
||||
import libKonogonka.fs.NSO.NSO0Header;
|
||||
import libKonogonka.fs.NSO.NSO0Provider;
|
||||
import nsusbloader.ModelControllers.ILogPrinter;
|
||||
import nsusbloader.NSLDataTypes.EMsgType;
|
||||
import nsusbloader.Utilities.patches.BinToAsmPrinter;
|
||||
import nsusbloader.Utilities.patches.es.finders.HeuristicEsWizard;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class EsPatch {
|
||||
private static final byte[] HEADER = "PATCH".getBytes(StandardCharsets.US_ASCII);
|
||||
private static final byte[] FOOTER = "EOF".getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
private final NCAProvider ncaProvider;
|
||||
private final String saveToLocation;
|
||||
private final ILogPrinter logPrinter;
|
||||
|
||||
private Long fwVersion;
|
||||
private String buildId;
|
||||
private byte[] _textSection;
|
||||
|
||||
private HeuristicEsWizard wizard;
|
||||
|
||||
EsPatch(NCAProvider ncaProvider, String saveToLocation, ILogPrinter logPrinter) throws Exception{
|
||||
this.ncaProvider = ncaProvider;
|
||||
this.saveToLocation = saveToLocation + File.separator +
|
||||
"atmosphere" + File.separator + "exefs_patches" + File.separator + "es_patches";
|
||||
this.logPrinter = logPrinter;
|
||||
|
||||
getPlainFirmwareVersion();
|
||||
NSO0Provider nso0Provider = new NSO0Provider(ncaProvider.getNCAContentProvider(0).getPfs0().getStreamProducer(0));
|
||||
getBuildId(nso0Provider);
|
||||
getTextSection(nso0Provider);
|
||||
findAllOffsets();
|
||||
mkDirs();
|
||||
writeFile();
|
||||
logPrinter.print(" == Debug information ==\n"+wizard.getDebug(), EMsgType.NULL);
|
||||
}
|
||||
private void getPlainFirmwareVersion() throws Exception{
|
||||
final byte[] byteSdkVersion = ncaProvider.getSdkVersion();
|
||||
fwVersion = Long.parseLong(""+byteSdkVersion[3]+byteSdkVersion[2]+byteSdkVersion[1]+byteSdkVersion[0]);
|
||||
logPrinter.print("Internal firmware version: "+byteSdkVersion[3] +"."+byteSdkVersion[2] +"."+byteSdkVersion[1] +"."+byteSdkVersion[0], EMsgType.INFO);
|
||||
if (byteSdkVersion[3] < 9 || fwVersion < 9300)
|
||||
logPrinter.print("WARNING! FIRMWARES VERSIONS BEFORE 9.0.0 ARE NOT SUPPORTED! USING PRODUCED ES PATCHES (IF ANY) COULD BREAK SOMETHING! IT'S NEVER BEEN TESTED!", EMsgType.WARNING);
|
||||
}
|
||||
private void getBuildId(NSO0Provider nso0Provider) throws Exception{
|
||||
NSO0Header nso0DecompressedHeader = nso0Provider.getAsDecompressedNSO0().getHeader();
|
||||
byte[] buildIdBytes = nso0DecompressedHeader.getModuleId();
|
||||
buildId = Converter.byteArrToHexStringAsLE(buildIdBytes).substring(0, 40).toUpperCase();
|
||||
logPrinter.print("Build ID: "+buildId, EMsgType.INFO);
|
||||
}
|
||||
private void getTextSection(NSO0Provider nso0Provider) throws Exception{
|
||||
_textSection = nso0Provider.getAsDecompressedNSO0().getTextRaw();
|
||||
}
|
||||
private void findAllOffsets() throws Exception{
|
||||
this.wizard = new HeuristicEsWizard(fwVersion, _textSection);
|
||||
String errorsAndNotes = wizard.getErrorsAndNotes();
|
||||
if (errorsAndNotes.length() > 0)
|
||||
logPrinter.print(errorsAndNotes, EMsgType.WARNING);
|
||||
}
|
||||
private void mkDirs(){
|
||||
File parentFolder = new File(saveToLocation);
|
||||
parentFolder.mkdirs();
|
||||
}
|
||||
|
||||
private void writeFile() throws Exception{
|
||||
String patchFileLocation = saveToLocation + File.separator + buildId + ".ips";
|
||||
int offset1 = wizard.getOffset1();
|
||||
int offset2 = wizard.getOffset2();
|
||||
int offset3 = wizard.getOffset3();
|
||||
|
||||
ByteBuffer handyEsPatch = ByteBuffer.allocate(0x23).order(ByteOrder.LITTLE_ENDIAN);
|
||||
handyEsPatch.put(HEADER);
|
||||
if (offset1 > 0) {
|
||||
logPrinter.print("Patch component 1 will be used", EMsgType.PASS);
|
||||
handyEsPatch.put(getPatch1(offset1));
|
||||
}
|
||||
if (offset2 > 0) {
|
||||
logPrinter.print("Patch component 2 will be used", EMsgType.PASS);
|
||||
handyEsPatch.put(getPatch2(offset2));
|
||||
}
|
||||
if (offset3 > 0) {
|
||||
logPrinter.print("Patch component 3 will be used", EMsgType.PASS);
|
||||
handyEsPatch.put(getPatch3(offset3));
|
||||
}
|
||||
handyEsPatch.put(FOOTER);
|
||||
|
||||
byte[] esPatch = new byte[handyEsPatch.position()];
|
||||
((Buffer) handyEsPatch).rewind();
|
||||
handyEsPatch.get(esPatch);
|
||||
|
||||
try (BufferedOutputStream stream = new BufferedOutputStream(
|
||||
Files.newOutputStream(Paths.get(patchFileLocation)))){
|
||||
stream.write(esPatch);
|
||||
}
|
||||
|
||||
logPrinter.print("Patch created at "+patchFileLocation, EMsgType.PASS);
|
||||
}
|
||||
|
||||
// WE EXPECT TO SEE CBZ (for patch 1) INSTRUCTION RIGHT BEFORE FOUND SEQUENCE (requiredInstructionOffsetInternal)
|
||||
// IN RESULTING FILE InstructionOffset SHOULD BE INCREMENTED by 0x100 to get real offset
|
||||
// (because header for decompressed NSO0 size = 0x100; it's fixed alignment produced by libKonogonka)
|
||||
private byte[] getPatch1(int offset) throws Exception{
|
||||
int requiredInstructionOffsetInternal = offset - 4;
|
||||
int requiredInstructionOffsetReal = requiredInstructionOffsetInternal + 0x100;
|
||||
int instructionExpression = Converter.getLEint(_textSection, requiredInstructionOffsetInternal);
|
||||
int patch = ((0x14 << 24) | (instructionExpression >> 5) & 0x7FFFF);
|
||||
|
||||
logPrinter.print(BinToAsmPrinter.printSimplified(patch, requiredInstructionOffsetInternal), EMsgType.NULL);
|
||||
|
||||
// Somehow IPS patches uses offsets written as big_endian (0.o) and bytes dat should be patched as LE.
|
||||
ByteBuffer prePatch = ByteBuffer.allocate(10).order(ByteOrder.BIG_ENDIAN)
|
||||
.putInt(requiredInstructionOffsetReal)
|
||||
.putShort((short) 4)
|
||||
.putInt(Integer.reverseBytes(patch));
|
||||
|
||||
return Arrays.copyOfRange(prePatch.array(), 1, 10);
|
||||
}
|
||||
private byte[] getPatch2(int offset) throws Exception{
|
||||
final int NopInstruction = 0x1F2003D5; // reversed
|
||||
int offsetReal = offset - 4 + 0x100;
|
||||
|
||||
logPrinter.print(BinToAsmPrinter.printSimplified(Integer.reverseBytes(NopInstruction), offset - 4), EMsgType.NULL);
|
||||
|
||||
ByteBuffer prePatch = ByteBuffer.allocate(10).order(ByteOrder.BIG_ENDIAN)
|
||||
.putInt(offsetReal)
|
||||
.putShort((short) 4)
|
||||
.putInt(NopInstruction);
|
||||
|
||||
return Arrays.copyOfRange(prePatch.array(), 1, 10);
|
||||
}
|
||||
private byte[] getPatch3(int offset) throws Exception{
|
||||
int requiredInstructionOffsetInternal = offset - 4;
|
||||
int requiredInstructionOffsetReal = requiredInstructionOffsetInternal + 0x100;
|
||||
|
||||
int instructionExpression = Converter.getLEint(_textSection, requiredInstructionOffsetInternal);
|
||||
int patch = ((0x14 << 24) | (instructionExpression >> 5) & 0x7FFFF);
|
||||
|
||||
logPrinter.print(BinToAsmPrinter.printSimplified(patch, requiredInstructionOffsetInternal), EMsgType.NULL);
|
||||
|
||||
ByteBuffer prePatch = ByteBuffer.allocate(10).order(ByteOrder.BIG_ENDIAN)
|
||||
.putInt(requiredInstructionOffsetReal)
|
||||
.putShort((short) 4)
|
||||
.putInt(Integer.reverseBytes(patch));
|
||||
|
||||
return Arrays.copyOfRange(prePatch.array(), 1, 10);
|
||||
}
|
||||
}
|
|
@ -1,182 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2022 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.es;
|
||||
|
||||
import libKonogonka.KeyChainHolder;
|
||||
import libKonogonka.fs.NCA.NCAProvider;
|
||||
import nsusbloader.ModelControllers.CancellableRunnable;
|
||||
import nsusbloader.ModelControllers.ILogPrinter;
|
||||
import nsusbloader.ModelControllers.Log;
|
||||
import nsusbloader.NSLDataTypes.EModule;
|
||||
import nsusbloader.NSLDataTypes.EMsgType;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public class EsPatchMaker extends CancellableRunnable {
|
||||
private int THREADS_POOL_SIZE;
|
||||
private final ILogPrinter logPrinter;
|
||||
private final String pathToFirmware;
|
||||
private final String pathToKeysFile;
|
||||
private final String saveTo;
|
||||
|
||||
private File firmware;
|
||||
private KeyChainHolder keyChainHolder;
|
||||
private ExecutorService executorService;
|
||||
private List<String> ncaFilesList; // inside the folder
|
||||
|
||||
private boolean oneLinerStatus = false;
|
||||
|
||||
public EsPatchMaker(String pathToFirmware, String pathToKeysFile, String saveTo){
|
||||
this.logPrinter = Log.getPrinter(EModule.PATCHES);
|
||||
/*
|
||||
this.logPrinter = new ILogPrinter() {
|
||||
public void print(String message, EMsgType type) throws InterruptedException {}
|
||||
public void updateProgress(Double value) throws InterruptedException {}
|
||||
public void update(HashMap<String, File> nspMap, EFileStatus status) {}
|
||||
public void update(File file, EFileStatus status) {}
|
||||
public void updateOneLinerStatus(boolean status) {}
|
||||
public void close() {}
|
||||
};
|
||||
*/
|
||||
this.pathToFirmware = pathToFirmware;
|
||||
this.pathToKeysFile = pathToKeysFile;
|
||||
this.saveTo = saveTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
logPrinter.print("..:: Make ES Patches ::..", EMsgType.INFO);
|
||||
receiveFirmware();
|
||||
buildKeyChainHolder();
|
||||
receiveNcaFileNamesList();
|
||||
specifyThreadsPoolSize();
|
||||
createPool();
|
||||
executePool();
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
try{
|
||||
logPrinter.print(e.getMessage(), EMsgType.FAIL);
|
||||
} catch (Exception ignore){}
|
||||
}
|
||||
finally {
|
||||
logPrinter.updateOneLinerStatus(oneLinerStatus);
|
||||
logPrinter.close();
|
||||
}
|
||||
}
|
||||
private void receiveFirmware() throws Exception{
|
||||
logPrinter.print("Looking at firmware", EMsgType.INFO);
|
||||
this.firmware = new File(pathToFirmware);
|
||||
if (! firmware.exists())
|
||||
throw new Exception("Firmware directory does not exist " + pathToFirmware);
|
||||
}
|
||||
private void buildKeyChainHolder() throws Exception{
|
||||
logPrinter.print("Reading keys", EMsgType.INFO);
|
||||
this.keyChainHolder = new KeyChainHolder(pathToKeysFile, null);
|
||||
}
|
||||
private void receiveNcaFileNamesList() throws Exception{
|
||||
logPrinter.print("Collecting NCA files", EMsgType.INFO);
|
||||
String[] fileNamesArray = firmware.list((File directory, String file) -> ( ! file.endsWith(".cnmt.nca") && file.endsWith(".nca")));
|
||||
ncaFilesList = Arrays.asList(Objects.requireNonNull(fileNamesArray));
|
||||
if (ncaFilesList.size() == 0)
|
||||
throw new Exception("No NCA files found in firmware folder");
|
||||
}
|
||||
private void specifyThreadsPoolSize(){
|
||||
THREADS_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors()+1, 4);
|
||||
THREADS_POOL_SIZE = Math.min(THREADS_POOL_SIZE, ncaFilesList.size());
|
||||
}
|
||||
|
||||
private void createPool() throws Exception{
|
||||
logPrinter.print("Creating sub-tasks pool", EMsgType.INFO);
|
||||
this.executorService = Executors.newFixedThreadPool(
|
||||
THREADS_POOL_SIZE,
|
||||
runnable -> {
|
||||
Thread thread = new Thread(runnable);
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
});
|
||||
}
|
||||
|
||||
private void executePool() throws Exception{ //TODO: FIX. Exceptions thrown only by logPrinter
|
||||
try {
|
||||
logPrinter.print("Executing sub-tasks pool", EMsgType.INFO);
|
||||
List<Future<NCAProvider>> futuresResults = executorService.invokeAll(getSubTasksCollection());
|
||||
for (Future<NCAProvider> future : futuresResults){
|
||||
NCAProvider ncaProvider = future.get();
|
||||
if (ncaProvider != null) {
|
||||
makePatches(ncaProvider);
|
||||
break;
|
||||
}
|
||||
}
|
||||
executorService.shutdown();
|
||||
}
|
||||
catch (InterruptedException ie){
|
||||
executorService.shutdownNow();
|
||||
boolean interruptedSuccessfully = false;
|
||||
try {
|
||||
interruptedSuccessfully = executorService.awaitTermination(20, TimeUnit.SECONDS);
|
||||
}
|
||||
catch (InterruptedException awaitInterrupt){
|
||||
logPrinter.print("Force interrupting task...", EMsgType.WARNING);
|
||||
}
|
||||
logPrinter.print("Task interrupted "+(interruptedSuccessfully?"successfully":"with some issues"), EMsgType.WARNING);
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
logPrinter.print("Task failed: "+e.getMessage(), EMsgType.FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
private void makePatches(NCAProvider ncaProvider) throws Exception{
|
||||
logPrinter.print(String.format("File found: .."+File.separator+"%s"+File.separator+"%s",
|
||||
ncaProvider.getFile().getParentFile().getName(), ncaProvider.getFile().getName())
|
||||
, EMsgType.INFO);
|
||||
new EsPatch(ncaProvider, saveTo, logPrinter);
|
||||
oneLinerStatus = true;
|
||||
}
|
||||
private List<Callable<NCAProvider>> getSubTasksCollection() throws Exception{
|
||||
logPrinter.print("Forming sub-tasks collection", EMsgType.INFO);
|
||||
List<Callable<NCAProvider>> subTasks = new ArrayList<>();
|
||||
|
||||
int ncaPerThreadAmount = ncaFilesList.size() / THREADS_POOL_SIZE;
|
||||
Iterator<String> iterator = ncaFilesList.listIterator();
|
||||
|
||||
for (int i = 1; i < THREADS_POOL_SIZE; i++){
|
||||
Callable<NCAProvider> task = new EsNcaSearchTask(getNextSet(iterator, ncaPerThreadAmount));
|
||||
subTasks.add(task);
|
||||
}
|
||||
int leftovers = ncaFilesList.size() % THREADS_POOL_SIZE;
|
||||
Callable<NCAProvider> task = new EsNcaSearchTask(getNextSet(iterator, ncaPerThreadAmount+leftovers));
|
||||
subTasks.add(task);
|
||||
return subTasks;
|
||||
}
|
||||
private List<NCAProvider> getNextSet(Iterator<String> iterator, int amount) throws Exception{
|
||||
List<NCAProvider> ncas = new ArrayList<>();
|
||||
for (int j = 0; j < amount; j++){
|
||||
String ncaFileName = iterator.next();
|
||||
File nca = new File(firmware.getAbsolutePath()+File.separator+ncaFileName);
|
||||
NCAProvider provider = new NCAProvider(nca, keyChainHolder.getRawKeySet());
|
||||
ncas.add(provider);
|
||||
}
|
||||
return ncas;
|
||||
}
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2022 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.es.finders;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import nsusbloader.AppPreferences;
|
||||
import nsusbloader.Utilities.patches.AHeuristic;
|
||||
import nsusbloader.Utilities.patches.BinToAsmPrinter;
|
||||
import nsusbloader.Utilities.patches.SimplyFind;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class HeuristicEs1 extends AHeuristic {
|
||||
private static final String PATTERN = AppPreferences.getInstance().getPatchPattern("ES", 1, 0);
|
||||
|
||||
private final List<Integer> findings;
|
||||
private final byte[] where;
|
||||
|
||||
HeuristicEs1(byte[] where){
|
||||
this.where = where;
|
||||
SimplyFind simplyfind = new SimplyFind(PATTERN, where);
|
||||
this.findings = simplyfind.getResults();
|
||||
|
||||
this.findings.removeIf(this::dropStep1);
|
||||
if(findings.size() < 2)
|
||||
return;
|
||||
|
||||
this.findings.removeIf(this::dropStep2);
|
||||
}
|
||||
|
||||
// Check ranges
|
||||
private boolean dropStep1(int offsetOfPatternFound){
|
||||
return ((offsetOfPatternFound < 0x10000 || offsetOfPatternFound > 0xffffc));
|
||||
}
|
||||
// Remove non-CBZ
|
||||
private boolean dropStep2(int offsetOfPatternFound){
|
||||
return ((where[offsetOfPatternFound - 1] & (byte) 0b01111111) != 0x34);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFound(){
|
||||
return findings.size() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wantLessEntropy(){
|
||||
return findings.size() > 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() throws Exception{
|
||||
if(findings.isEmpty())
|
||||
throw new Exception("Nothing found");
|
||||
if (findings.size() > 1)
|
||||
throw new Exception("Too many offsets");
|
||||
return findings.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setOffsetsNearby(int offsetNearby) {
|
||||
findings.removeIf(offset -> {
|
||||
if (offset > offsetNearby)
|
||||
return ! (offset < offsetNearby - 0xffff);
|
||||
return ! (offset > offsetNearby - 0xffff);
|
||||
});
|
||||
return isFound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetails(){
|
||||
int cbzOffsetInternal = findings.get(0) - 4;
|
||||
int instructionExpression = Converter.getLEint(where, cbzOffsetInternal);
|
||||
int conditionalJumpLocation = ((instructionExpression >> 5 & 0x7FFFF) * 4 + cbzOffsetInternal) & 0xfffff;
|
||||
|
||||
int secondExpressionsPairElement1 = Converter.getLEint(where, conditionalJumpLocation);
|
||||
int secondExpressionsPairElement2 = Converter.getLEint(where, conditionalJumpLocation+4);
|
||||
|
||||
return BinToAsmPrinter.printSimplified(instructionExpression, cbzOffsetInternal) +
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(where, cbzOffsetInternal + 4),
|
||||
cbzOffsetInternal + 4) +
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(where, cbzOffsetInternal + 8),
|
||||
cbzOffsetInternal + 8) +
|
||||
"...\n" +
|
||||
BinToAsmPrinter.printSimplified(secondExpressionsPairElement1, conditionalJumpLocation) +
|
||||
BinToAsmPrinter.printSimplified(secondExpressionsPairElement2, conditionalJumpLocation + 4);
|
||||
}
|
||||
}
|
|
@ -1,161 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2022 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.es.finders;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import nsusbloader.AppPreferences;
|
||||
import nsusbloader.Utilities.patches.AHeuristic;
|
||||
import nsusbloader.Utilities.patches.BinToAsmPrinter;
|
||||
import nsusbloader.Utilities.patches.SimplyFind;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class HeuristicEs2 extends AHeuristic {
|
||||
private static final String PATTERN = AppPreferences.getInstance().getPatchPattern("ES", 2, 0);
|
||||
|
||||
private List<Integer> findings;
|
||||
private final byte[] where;
|
||||
|
||||
HeuristicEs2(byte[] where){
|
||||
this.where = where;
|
||||
find();
|
||||
|
||||
this.findings.removeIf(this::dropStep1);
|
||||
if(findings.size() < 2)
|
||||
return;
|
||||
|
||||
this.findings.removeIf(this::dropStep2);
|
||||
if(findings.size() < 2)
|
||||
return;
|
||||
|
||||
this.findings.removeIf(this::dropStep3);
|
||||
if(findings.size() < 2)
|
||||
return;
|
||||
|
||||
this.findings.removeIf(this::dropStep4);
|
||||
if(findings.size() < 2)
|
||||
return;
|
||||
|
||||
this.findings.removeIf(this::dropStep5);
|
||||
if(findings.size() < 2)
|
||||
return;
|
||||
|
||||
this.findings.removeIf(this::dropStep6);
|
||||
}
|
||||
private void find(){
|
||||
SimplyFind simplyfind = new SimplyFind(PATTERN, where);
|
||||
findings = new ArrayList<>();
|
||||
// This approach a bit different. We're looking for pattern we want to patch, not the next one.
|
||||
// So easier way is just to shift every value and pretend that nothing happened.
|
||||
for (int offset : simplyfind.getResults())
|
||||
findings.add(offset+4);
|
||||
}
|
||||
|
||||
// Limit range
|
||||
private boolean dropStep1(int offsetOfPatternFound){
|
||||
return ((offsetOfPatternFound < 0x10000 || offsetOfPatternFound > 0xffffc));
|
||||
}
|
||||
// Is CBNZ next?
|
||||
private boolean dropStep2(int offsetOfPatternFound){
|
||||
return ! isCBNZ(Converter.getLEint(where, offsetOfPatternFound));
|
||||
}
|
||||
// Check what's above
|
||||
private boolean dropStep3(int offsetOfPatternFound){
|
||||
return ! isMOV(Converter.getLEint(where, offsetOfPatternFound-4));
|
||||
}
|
||||
// Check what's beyond or after jump
|
||||
private boolean dropStep4(int offsetOfPatternFound) {
|
||||
int nextExpression = Converter.getLEint(where, offsetOfPatternFound + 4);
|
||||
return ! isLDRB_LDURB(nextExpression); // Drop if not LDRB OR LDURB
|
||||
}
|
||||
|
||||
// Check second after jump if LDR-TBZ
|
||||
private boolean dropStep5(int offsetOfPatternFound) {
|
||||
int expression = Converter.getLEint(where, offsetOfPatternFound);
|
||||
int afterJumpPosition = ((expression >> 5 & 0x7FFFF) * 4 + offsetOfPatternFound) & 0xfffff;
|
||||
int secondAfterJumpExpression = Converter.getLEint(where, afterJumpPosition+4);
|
||||
return ! isBL(secondAfterJumpExpression); //Second after jump = BL? No -> Drop
|
||||
}
|
||||
|
||||
// Check second after jump if LDR-TBZ
|
||||
private boolean dropStep6(int offsetOfPatternFound) {
|
||||
int expression = Converter.getLEint(where, offsetOfPatternFound);
|
||||
int afterJumpPosition = ((expression >> 5 & 0x7FFFF) * 4 + offsetOfPatternFound) & 0xfffff;
|
||||
int forthAfterJumpExpression = Converter.getLEint(where, afterJumpPosition+12);
|
||||
return ! isBL(forthAfterJumpExpression); //Forth after jump = BL? No -> Drop
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFound(){
|
||||
return findings.size() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wantLessEntropy(){
|
||||
return findings.size() > 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() throws Exception{
|
||||
if(findings.isEmpty())
|
||||
throw new Exception("Nothing found");
|
||||
if (findings.size() > 1)
|
||||
throw new Exception("Too many offsets");
|
||||
return findings.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setOffsetsNearby(int offsetNearby) {
|
||||
findings.removeIf(offset -> {
|
||||
if (offset > offsetNearby)
|
||||
return ! (offset < offsetNearby - 0xffff);
|
||||
return ! (offset > offsetNearby - 0xffff);
|
||||
});
|
||||
return isFound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetails(){
|
||||
int secondExpressionOffset = findings.get(0);
|
||||
|
||||
int firstExpression = Converter.getLEint(where, secondExpressionOffset-4);
|
||||
int secondExpression = Converter.getLEint(where, secondExpressionOffset);
|
||||
int conditionalJumpLocation = 0;
|
||||
if ((secondExpression >> 24 & 0x7f) == 0x35) {
|
||||
conditionalJumpLocation = ((secondExpression >> 5 & 0x7FFFF) * 4 + secondExpressionOffset) & 0xfffff;
|
||||
}
|
||||
else if ((firstExpression >> 24 & 0x7f) == 0x36) {
|
||||
conditionalJumpLocation = (secondExpressionOffset-4 + (firstExpression >> 5 & 0x3fff) * 4) & 0xfffff;
|
||||
}
|
||||
int secondExpressionsPairElement1 = Converter.getLEint(where, conditionalJumpLocation);
|
||||
int secondExpressionsPairElement2 = Converter.getLEint(where, conditionalJumpLocation + 4);
|
||||
int secondExpressionsPairElement3 = Converter.getLEint(where, conditionalJumpLocation + 8);
|
||||
int secondExpressionsPairElement4 = Converter.getLEint(where, conditionalJumpLocation + 12);
|
||||
|
||||
return BinToAsmPrinter.printSimplified(Converter.getLEint(where, secondExpressionOffset - 4), secondExpressionOffset - 4) +
|
||||
BinToAsmPrinter.printSimplified(secondExpression, secondExpressionOffset) +
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(where, secondExpressionOffset + 4), secondExpressionOffset + 4) +
|
||||
"...\n" +
|
||||
BinToAsmPrinter.printSimplified(secondExpressionsPairElement1, conditionalJumpLocation) +
|
||||
BinToAsmPrinter.printSimplified(secondExpressionsPairElement2, conditionalJumpLocation + 4) +
|
||||
BinToAsmPrinter.printSimplified(secondExpressionsPairElement3, conditionalJumpLocation + 8) +
|
||||
BinToAsmPrinter.printSimplified(secondExpressionsPairElement4, conditionalJumpLocation + 12);
|
||||
}
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2022 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.es.finders;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import nsusbloader.AppPreferences;
|
||||
import nsusbloader.Utilities.patches.AHeuristic;
|
||||
import nsusbloader.Utilities.patches.BinToAsmPrinter;
|
||||
import nsusbloader.Utilities.patches.SimplyFind;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class HeuristicEs3 extends AHeuristic {
|
||||
private static final String PATTERN0 = AppPreferences.getInstance().getPatchPattern("ES", 3, 0);
|
||||
private static final String PATTERN1 = AppPreferences.getInstance().getPatchPattern("ES", 3, 1);
|
||||
|
||||
private final List<Integer> findings;
|
||||
private final byte[] where;
|
||||
|
||||
HeuristicEs3(long fwVersion, byte[] where){
|
||||
this.where = where;
|
||||
String pattern = getPattern(fwVersion);
|
||||
SimplyFind simplyfind = new SimplyFind(pattern, where);
|
||||
this.findings = simplyfind.getResults();
|
||||
|
||||
this.findings.removeIf(this::dropStep1);
|
||||
if(findings.size() < 2)
|
||||
return;
|
||||
|
||||
this.findings.removeIf(this::dropStep2);
|
||||
if(findings.size() < 2)
|
||||
return;
|
||||
|
||||
this.findings.removeIf(this::dropStep3);
|
||||
}
|
||||
private String getPattern(long fwVersion){
|
||||
if (fwVersion < 10400)
|
||||
return PATTERN0;
|
||||
return PATTERN1;
|
||||
}
|
||||
// Let's focus on CBZ-ONLY statements
|
||||
private boolean dropStep1(int offsetOfPatternFound){
|
||||
return ((where[offsetOfPatternFound - 1] & (byte) 0b01111111) != 0x34);
|
||||
}
|
||||
|
||||
private boolean dropStep2(int offsetOfPatternFound){
|
||||
int conditionalJumpLocation = getCBZConditionalJumpLocation(offsetOfPatternFound - 4);
|
||||
|
||||
int afterJumpSecondExpressions = Converter.getLEint(where, conditionalJumpLocation);
|
||||
int afterJumpThirdExpressions = Converter.getLEint(where, conditionalJumpLocation+4);
|
||||
// Check first is 'MOV'; second is 'B'
|
||||
return (! isMOV_REG(afterJumpSecondExpressions)) || ! isB(afterJumpThirdExpressions);
|
||||
}
|
||||
|
||||
private boolean dropStep3(int offsetOfPatternFound){
|
||||
int conditionalJumpLocation = getCBZConditionalJumpLocation(offsetOfPatternFound-4);
|
||||
int afterJumpSecondExpressions = Converter.getLEint(where, conditionalJumpLocation+4);
|
||||
int secondPairConditionalJumpLocation = ((afterJumpSecondExpressions & 0x3ffffff) * 4 + (conditionalJumpLocation+4)) & 0xfffff;
|
||||
|
||||
int thirdExpressionsPairElement1 = Converter.getLEint(where, secondPairConditionalJumpLocation);
|
||||
int thirdExpressionsPairElement2 = Converter.getLEint(where, secondPairConditionalJumpLocation+4);
|
||||
// Check first is 'ADD'; second is 'BL'
|
||||
return (! isADD(thirdExpressionsPairElement1)) || (! isBL(thirdExpressionsPairElement2));
|
||||
}
|
||||
|
||||
private int getCBZConditionalJumpLocation(int cbzOffsetInternal){
|
||||
int cbzExpression = Converter.getLEint(where, cbzOffsetInternal);
|
||||
return ((cbzExpression >> 5 & 0x7FFFF) * 4 + cbzOffsetInternal) & 0xfffff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFound(){
|
||||
return findings.size() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wantLessEntropy(){
|
||||
return findings.size() > 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() throws Exception{
|
||||
if(findings.isEmpty())
|
||||
throw new Exception("Nothing found");
|
||||
if (findings.size() > 1)
|
||||
throw new Exception("Too many offsets");
|
||||
return findings.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setOffsetsNearby(int offsetNearby) {
|
||||
findings.removeIf(offset -> {
|
||||
if (offset > offsetNearby)
|
||||
return ! (offset < offsetNearby - 0xffff);
|
||||
return ! (offset > offsetNearby - 0xffff);
|
||||
});
|
||||
return isFound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetails(){
|
||||
int cbzOffsetInternal = findings.get(0) - 4;
|
||||
int cbzExpression = Converter.getLEint(where, cbzOffsetInternal);
|
||||
int conditionalJumpLocation = ((cbzExpression >> 5 & 0x7FFFF) * 4 + cbzOffsetInternal) & 0xfffff;
|
||||
|
||||
int secondExpressionsPairElement1 = Converter.getLEint(where, conditionalJumpLocation);
|
||||
int secondExpressionsPairElement2 = Converter.getLEint(where, conditionalJumpLocation+4);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(BinToAsmPrinter.printSimplified(cbzExpression, cbzOffsetInternal));
|
||||
builder.append(BinToAsmPrinter.printSimplified(Converter.getLEint(where, cbzOffsetInternal+4), cbzOffsetInternal+4));
|
||||
builder.append(BinToAsmPrinter.printSimplified(Converter.getLEint(where, cbzOffsetInternal+8), cbzOffsetInternal+8));
|
||||
builder.append("...\n");
|
||||
|
||||
builder.append(BinToAsmPrinter.printSimplified(secondExpressionsPairElement1, conditionalJumpLocation));
|
||||
builder.append(BinToAsmPrinter.printSimplified(secondExpressionsPairElement2, conditionalJumpLocation+4));
|
||||
|
||||
if (((secondExpressionsPairElement2 >> 26 & 0b111111) == 0x5)){
|
||||
builder.append("...\n");
|
||||
int conditionalJumpLocation2 = ((secondExpressionsPairElement2 & 0x3ffffff) * 4 + (conditionalJumpLocation+4)) & 0xfffff;
|
||||
|
||||
builder.append(BinToAsmPrinter.printSimplified(Converter.getLEint(where, conditionalJumpLocation2), conditionalJumpLocation2));
|
||||
builder.append(BinToAsmPrinter.printSimplified(Converter.getLEint(where, conditionalJumpLocation2+4), conditionalJumpLocation2+4));
|
||||
}
|
||||
else {
|
||||
builder.append("NO CONDITIONAL JUMP ON 2nd iteration (HeuristicEs3)");
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2022 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.es.finders;
|
||||
|
||||
import nsusbloader.Utilities.patches.AHeuristic;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class HeuristicEsWizard {
|
||||
private final List<AHeuristic> all;
|
||||
private final List<AHeuristic> found;
|
||||
private final List<AHeuristic> wantLessEntropy;
|
||||
|
||||
private final StringBuilder errorsAndNotes;
|
||||
|
||||
private int offset1 = -1;
|
||||
private int offset2 = -1;
|
||||
private int offset3 = -1;
|
||||
|
||||
public HeuristicEsWizard(long fwVersion, byte[] where) throws Exception{
|
||||
this.errorsAndNotes = new StringBuilder();
|
||||
|
||||
this.all = Arrays.asList(
|
||||
new HeuristicEs1(where),
|
||||
new HeuristicEs2(where),
|
||||
new HeuristicEs3(fwVersion, where)
|
||||
);
|
||||
|
||||
this.found = all.stream()
|
||||
.filter(AHeuristic::isFound)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (found.isEmpty())
|
||||
throw new Exception("Nothing found!");
|
||||
|
||||
this.wantLessEntropy = all.stream()
|
||||
.filter(AHeuristic::wantLessEntropy)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
shareOffsetsWithEachOther();
|
||||
|
||||
assignOffset1();
|
||||
assignOffset2();
|
||||
assignOffset3();
|
||||
}
|
||||
|
||||
private void shareOffsetsWithEachOther(){
|
||||
for (AHeuristic es : wantLessEntropy) {
|
||||
if (shareWithNext(es))
|
||||
return;
|
||||
}
|
||||
}
|
||||
private boolean shareWithNext(AHeuristic es){
|
||||
try {
|
||||
for (AHeuristic foundEs : found) {
|
||||
if (es.setOffsetsNearby(foundEs.getOffset())) {
|
||||
found.add(es);
|
||||
wantLessEntropy.remove(es);
|
||||
shareOffsetsWithEachOther();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e){ e.printStackTrace(); }
|
||||
return false;
|
||||
}
|
||||
|
||||
private void assignOffset1(){
|
||||
try {
|
||||
offset1 = all.get(0).getOffset();
|
||||
}
|
||||
catch (Exception e){ errorsAndNotes.append(e.getLocalizedMessage()).append("\n"); }
|
||||
}
|
||||
private void assignOffset2(){
|
||||
try {
|
||||
offset2 = all.get(1).getOffset();
|
||||
}
|
||||
catch (Exception e){ errorsAndNotes.append(e.getLocalizedMessage()).append("\n"); }
|
||||
}
|
||||
private void assignOffset3(){
|
||||
try {
|
||||
offset3 = all.get(2).getOffset();
|
||||
}
|
||||
catch (Exception e){ errorsAndNotes.append(e.getLocalizedMessage()).append("\n"); }
|
||||
}
|
||||
|
||||
public String getErrorsAndNotes(){
|
||||
return errorsAndNotes.toString();
|
||||
}
|
||||
|
||||
public String getDebug(){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (all.get(0).isFound()){
|
||||
builder.append("\t\t-=== 1 ===-\n");
|
||||
builder.append(all.get(0).getDetails());
|
||||
}
|
||||
if (all.get(1).isFound()){
|
||||
builder.append("\t\t-=== 2 ===-\n");
|
||||
builder.append(all.get(1).getDetails());
|
||||
}
|
||||
if (all.get(2).isFound()){
|
||||
builder.append("\t\t-=== 3 ===-\n");
|
||||
builder.append(all.get(2).getDetails());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public int getOffset1() { return offset1; }
|
||||
public int getOffset2() { return offset2; }
|
||||
public int getOffset3() { return offset3; }
|
||||
}
|
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
Copyright 2019-2023 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.fs;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import nsusbloader.ModelControllers.ILogPrinter;
|
||||
import nsusbloader.NSLDataTypes.EMsgType;
|
||||
import nsusbloader.Utilities.patches.MalformedIniFileException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class FsIniMaker {
|
||||
private static final String FILE_HEADER_TEXT = "# UTF-8\n" +
|
||||
"# A KIP section is [kip1_name:sha256_hex_8bytes]\n" +
|
||||
"# A patchset is .patch_name=kip_section_dec:offset_hex_0x:length_hex_0x:src_data_hex,dst_data_hex\n" +
|
||||
"# _dec: 1 char decimal | _hex_0x: max u32 prefixed with 0x | _hex: hex array.\n" +
|
||||
"# Kip1 section decimals: TEXT: 0, RODATA: 1, DATA: 2.\n"; // Sending good vibes to Mr. ITotalJustice
|
||||
|
||||
private final ILogPrinter logPrinter;
|
||||
private final String saveToLocation;
|
||||
private final int offset1;
|
||||
private final int offset2;
|
||||
|
||||
private String firmwareVersionInformationNotice;
|
||||
private String sectionDeclaration;
|
||||
private String patchSet1;
|
||||
private String patchSet2;
|
||||
|
||||
public FsIniMaker(ILogPrinter logPrinter,
|
||||
String saveToLocation,
|
||||
byte[] _textSection,
|
||||
int wizardOffset1,
|
||||
int wizardOffset2,
|
||||
byte[] sdkVersion,
|
||||
String patchName,
|
||||
boolean filesystemTypeFat32) throws Exception{
|
||||
this.logPrinter = logPrinter;
|
||||
this.saveToLocation = saveToLocation;
|
||||
this.offset1 = wizardOffset1 - 4;
|
||||
this.offset2 = wizardOffset2 - 4;
|
||||
|
||||
mkDirs();
|
||||
makeFwVersionInformationNotice(filesystemTypeFat32, sdkVersion);
|
||||
makeSectionDeclaration(patchName);
|
||||
makePatchSet1(_textSection);
|
||||
makePatchSet2(_textSection);
|
||||
writeFile();
|
||||
}
|
||||
|
||||
private void mkDirs(){
|
||||
File parentFolder = new File(saveToLocation + File.separator + "bootloader");
|
||||
parentFolder.mkdirs();
|
||||
}
|
||||
|
||||
private void makeFwVersionInformationNotice(boolean isFat32, byte[] fwVersion){
|
||||
String fwVersionFormatted = fwVersion[3]+"."+fwVersion[2]+"."+fwVersion[1]+"."+fwVersion[0];
|
||||
if (isFat32)
|
||||
firmwareVersionInformationNotice = "\n#FS (FAT)"+fwVersionFormatted+"\n";
|
||||
else
|
||||
firmwareVersionInformationNotice = "\n#FS (ExFAT) "+fwVersionFormatted+"\n";
|
||||
}
|
||||
|
||||
private void makeSectionDeclaration(String patchName){
|
||||
sectionDeclaration = "[FS:"+patchName.substring(0, 16)+"]";
|
||||
}
|
||||
|
||||
private void makePatchSet1(byte[] _textSection){
|
||||
if (offset1 > 0) {
|
||||
byte[] originalInstruction = Arrays.copyOfRange(_textSection, offset1, offset1 + 4);
|
||||
patchSet1 = String.format(".nosigchk=0:0x%02X:0x4:%s,1F2003D5",
|
||||
offset1, Converter.byteArrToHexStringAsLE(originalInstruction, true));
|
||||
}
|
||||
}
|
||||
|
||||
private void makePatchSet2(byte[] _textSection){
|
||||
if (offset2 > 0) {
|
||||
byte[] originalInstruction = Arrays.copyOfRange(_textSection, offset2, offset2 + 4);
|
||||
patchSet2 = String.format(".nosigchk=0:0x%02X:0x4:%s,E0031F2A",
|
||||
offset2, Converter.byteArrToHexStringAsLE(originalInstruction, true));
|
||||
}
|
||||
}
|
||||
|
||||
private void writeFile() throws Exception{
|
||||
final String iniLocation = saveToLocation + File.separator + "bootloader" + File.separator + "patches.ini";
|
||||
final Path iniLocationPath = Paths.get(iniLocation);
|
||||
|
||||
boolean iniNotExists = Files.notExists(iniLocationPath);
|
||||
|
||||
try (RandomAccessFile ini = new RandomAccessFile(iniLocation, "rw")){
|
||||
if (iniNotExists)
|
||||
ini.writeBytes(FILE_HEADER_TEXT);
|
||||
else {
|
||||
String line;
|
||||
while ((line = ini.readLine()) != null){
|
||||
if (! line.startsWith(sectionDeclaration))
|
||||
continue;
|
||||
|
||||
if (offset1 > 0) {
|
||||
String expression1 = ini.readLine();
|
||||
if (expression1 == null || ! expression1.startsWith(patchSet1))
|
||||
throw new MalformedIniFileException("Somewhere near "+ini.getFilePointer());
|
||||
}
|
||||
String expression2 = ini.readLine();
|
||||
if (offset2 > 0) {
|
||||
if (expression2 == null || ! expression2.startsWith(patchSet2))
|
||||
throw new MalformedIniFileException("Somewhere near "+ini.getFilePointer());
|
||||
}
|
||||
else {
|
||||
if (expression2 == null || ! expression2.startsWith(".nosigchk"))
|
||||
return;
|
||||
throw new MalformedIniFileException("Somewhere near "+ini.getFilePointer());
|
||||
}
|
||||
return; // Ini file already contains correct information regarding patch file we made.
|
||||
}
|
||||
}
|
||||
|
||||
ini.writeBytes(firmwareVersionInformationNotice);
|
||||
ini.writeBytes(sectionDeclaration);
|
||||
ini.writeBytes("\n");
|
||||
|
||||
if (offset1 > 0) {
|
||||
ini.writeBytes(patchSet1);
|
||||
ini.writeBytes("\n");
|
||||
}
|
||||
if (offset2 > 0) {
|
||||
ini.writeBytes(patchSet2);
|
||||
ini.writeBytes("\n");
|
||||
}
|
||||
}
|
||||
catch (MalformedIniFileException e){
|
||||
e.printStackTrace();
|
||||
logPrinter.print(
|
||||
"Existing patches.ini file is malformed or contains incorrect (outdated) information regarding current patch.\n" +
|
||||
"It's now saved at "+iniLocation+".OLD\n" +
|
||||
"New patches.ini file created instead.", EMsgType.WARNING);
|
||||
Files.move(iniLocationPath, Paths.get(iniLocation+".OLD"),
|
||||
StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
|
||||
writeFile();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2023 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.fs;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import libKonogonka.fs.NCA.NCAProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
class FsNcaSearchTask implements Callable<List<NCAProvider>> {
|
||||
private final List<NCAProvider> ncaProviders;
|
||||
|
||||
FsNcaSearchTask(List<NCAProvider> ncaProviders){
|
||||
this.ncaProviders = ncaProviders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NCAProvider> call() {
|
||||
List<NCAProvider> result = new ArrayList<>();
|
||||
try {
|
||||
for (NCAProvider ncaProvider : ncaProviders) {
|
||||
String titleId = Converter.byteArrToHexStringAsLE(ncaProvider.getTitleId());
|
||||
if (titleId.equals("0100000000000819") || titleId.equals("010000000000081b")) // eq. FAT32 || exFAT
|
||||
result.add(ncaProvider);
|
||||
}
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,218 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2023 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
---
|
||||
Based on https://github.com/mrdude2478/IPS_Patch_Creator patch script made by GBATemp member MrDude.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.fs;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import libKonogonka.KeyChainHolder;
|
||||
import libKonogonka.fs.NCA.NCAProvider;
|
||||
import libKonogonka.fs.RomFs.FileSystemEntry;
|
||||
import libKonogonka.fs.RomFs.RomFsProvider;
|
||||
import libKonogonka.fs.other.System2.System2Provider;
|
||||
import libKonogonka.fs.other.System2.ini1.Ini1Provider;
|
||||
import libKonogonka.fs.other.System2.ini1.KIP1Provider;
|
||||
import libKonogonka.aesctr.InFileStreamProducer;
|
||||
import nsusbloader.ModelControllers.ILogPrinter;
|
||||
import nsusbloader.NSLDataTypes.EMsgType;
|
||||
import nsusbloader.Utilities.patches.BinToAsmPrinter;
|
||||
import nsusbloader.Utilities.patches.fs.finders.HeuristicFsWizard;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class FsPatch {
|
||||
private static final byte[] HEADER = "PATCH".getBytes(StandardCharsets.US_ASCII);
|
||||
private static final byte[] FOOTER = "EOF".getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
private final NCAProvider ncaProvider;
|
||||
private final String saveToLocation;
|
||||
private final KeyChainHolder keyChainHolder;
|
||||
private final ILogPrinter logPrinter;
|
||||
|
||||
private String patchName;
|
||||
private byte[] _textSection;
|
||||
private boolean filesystemTypeFat32;
|
||||
|
||||
private HeuristicFsWizard wizard;
|
||||
// Called twice: once for FAT32, once for ExFAT
|
||||
FsPatch(NCAProvider ncaProvider,
|
||||
String saveToLocation,
|
||||
KeyChainHolder keyChainHolder,
|
||||
ILogPrinter logPrinter) throws Exception{
|
||||
this.ncaProvider = ncaProvider;
|
||||
this.saveToLocation = saveToLocation;
|
||||
this.keyChainHolder = keyChainHolder;
|
||||
this.logPrinter = logPrinter;
|
||||
|
||||
KIP1Provider kip1Provider = getKIP1Provider();
|
||||
getPatchName(kip1Provider);
|
||||
getTextSection(kip1Provider);
|
||||
checkFirmwareVersion();
|
||||
getFilesystemType();
|
||||
findAllOffsets();
|
||||
mkDirs();
|
||||
writeFile();
|
||||
new FsIniMaker(logPrinter,
|
||||
saveToLocation,
|
||||
_textSection,
|
||||
wizard.getOffset1(),
|
||||
wizard.getOffset2(),
|
||||
ncaProvider.getSdkVersion(),
|
||||
patchName,
|
||||
filesystemTypeFat32);
|
||||
logPrinter.print(" == Debug information ==\n"+wizard.getDebug(), EMsgType.NULL);
|
||||
}
|
||||
private KIP1Provider getKIP1Provider() throws Exception{
|
||||
RomFsProvider romFsProvider = ncaProvider.getNCAContentProvider(0).getRomfs();
|
||||
|
||||
FileSystemEntry package2FsEntry = romFsProvider.getRootEntry().getContent()
|
||||
.stream()
|
||||
.filter(e -> e.getName().equals("nx"))
|
||||
.collect(Collectors.toList())
|
||||
.get(0)
|
||||
.getContent()
|
||||
.stream()
|
||||
.filter(e -> e.getName().equals("package2"))
|
||||
.collect(Collectors.toList())
|
||||
.get(0);
|
||||
InFileStreamProducer producer = romFsProvider.getStreamProducer(package2FsEntry);
|
||||
System2Provider system2Provider = new System2Provider(producer, keyChainHolder);
|
||||
Ini1Provider ini1Provider = system2Provider.getIni1Provider();
|
||||
|
||||
KIP1Provider kip1Provider = ini1Provider.getKip1List().stream()
|
||||
.filter(provider -> provider.getHeader().getName().startsWith("FS"))
|
||||
.collect(Collectors.toList())
|
||||
.get(0);
|
||||
|
||||
if (kip1Provider == null)
|
||||
throw new Exception("No FS KIP1");
|
||||
|
||||
return kip1Provider;
|
||||
}
|
||||
private void getPatchName(KIP1Provider kip1Provider) throws Exception{
|
||||
int kip1EncryptedSize = (int) kip1Provider.getSize();
|
||||
byte[] kip1EncryptedRaw = new byte[kip1EncryptedSize];
|
||||
|
||||
try (BufferedInputStream kip1ProviderStream = kip1Provider.getStreamProducer().produce()) {
|
||||
if (kip1EncryptedSize != kip1ProviderStream.read(kip1EncryptedRaw))
|
||||
throw new Exception("Unencrypted FS KIP1 read failure");
|
||||
}
|
||||
|
||||
byte[] sha256ofKip1 = MessageDigest.getInstance("SHA-256").digest(kip1EncryptedRaw);
|
||||
patchName = Converter.byteArrToHexStringAsLE(sha256ofKip1, true) + ".ips";
|
||||
}
|
||||
private void getTextSection(KIP1Provider kip1Provider) throws Exception{
|
||||
_textSection = kip1Provider.getAsDecompressed().getTextRaw();
|
||||
}
|
||||
private void checkFirmwareVersion() throws Exception{
|
||||
final byte[] byteSdkVersion = ncaProvider.getSdkVersion();
|
||||
long fwVersion = Long.parseLong(""+byteSdkVersion[3]+byteSdkVersion[2]+byteSdkVersion[1]+byteSdkVersion[0]);
|
||||
logPrinter.print("Internal firmware version: " + byteSdkVersion[3] +"."+ byteSdkVersion[2] +"."+ byteSdkVersion[1] +"."+ byteSdkVersion[0], EMsgType.INFO);
|
||||
if (byteSdkVersion[3] < 9 || fwVersion < 9300)
|
||||
logPrinter.print("WARNING! FIRMWARES VERSIONS BEFORE 9.0.0 ARE NOT SUPPORTED! " +
|
||||
"USING PRODUCED ES PATCHES (IF ANY) COULD BREAK SOMETHING! IT'S NEVER BEEN TESTED!", EMsgType.WARNING);
|
||||
}
|
||||
private void getFilesystemType() throws Exception{
|
||||
String titleId = Converter.byteArrToHexStringAsLE(ncaProvider.getTitleId());
|
||||
filesystemTypeFat32 = titleId.equals("0100000000000819");
|
||||
if (filesystemTypeFat32)
|
||||
logPrinter.print("\n\t\t-- [ FAT32 ] --\n", EMsgType.INFO);
|
||||
else
|
||||
logPrinter.print("\n\t\t-- [ ExFAT ] --\n", EMsgType.INFO);
|
||||
}
|
||||
private void findAllOffsets() throws Exception{
|
||||
this.wizard = new HeuristicFsWizard(_textSection);
|
||||
String errorsAndNotes = wizard.getErrorsAndNotes();
|
||||
if (errorsAndNotes.length() > 0)
|
||||
logPrinter.print(errorsAndNotes, EMsgType.WARNING);
|
||||
}
|
||||
private void mkDirs(){
|
||||
File parentFolder = new File(saveToLocation + File.separator +
|
||||
"atmosphere" + File.separator + "kip_patches" + File.separator + "fs_patches");
|
||||
parentFolder.mkdirs();
|
||||
}
|
||||
|
||||
private void writeFile() throws Exception{
|
||||
String patchFileLocation = saveToLocation + File.separator +
|
||||
"atmosphere" + File.separator + "kip_patches" + File.separator + "fs_patches" + File.separator + patchName;
|
||||
int offset1 = wizard.getOffset1();
|
||||
int offset2 = wizard.getOffset2();
|
||||
|
||||
ByteBuffer handyFsPatch = ByteBuffer.allocate(0x100).order(ByteOrder.LITTLE_ENDIAN);
|
||||
handyFsPatch.put(HEADER);
|
||||
if (offset1 > 0) {
|
||||
logPrinter.print("Patch component 1 will be used", EMsgType.PASS);
|
||||
handyFsPatch.put(getPatch1(offset1));
|
||||
}
|
||||
if (offset2 > 0) {
|
||||
logPrinter.print("Patch component 2 will be used", EMsgType.PASS);
|
||||
handyFsPatch.put(getPatch2(offset2));
|
||||
}
|
||||
handyFsPatch.put(FOOTER);
|
||||
|
||||
byte[] fsPatch = new byte[handyFsPatch.position()];
|
||||
((Buffer) handyFsPatch).rewind();
|
||||
handyFsPatch.get(fsPatch);
|
||||
|
||||
try (BufferedOutputStream stream = new BufferedOutputStream(
|
||||
Files.newOutputStream(Paths.get(patchFileLocation)))){
|
||||
stream.write(fsPatch);
|
||||
}
|
||||
logPrinter.print("Patch created at "+patchFileLocation, EMsgType.PASS);
|
||||
}
|
||||
|
||||
private byte[] getPatch1(int offset) throws Exception{
|
||||
int requiredInstructionOffsetInternal = offset - 4;
|
||||
int requiredInstructionOffsetReal = requiredInstructionOffsetInternal + 0x100;
|
||||
final int patch = 0x1F2003D5; // NOP
|
||||
|
||||
logPrinter.print(BinToAsmPrinter.printSimplified(Integer.reverseBytes(patch), requiredInstructionOffsetInternal), EMsgType.NULL);
|
||||
|
||||
// Somehow IPS patches uses offsets written as big_endian (0.o) and bytes dat should be patched as LE.
|
||||
ByteBuffer prePatch = ByteBuffer.allocate(10).order(ByteOrder.BIG_ENDIAN)
|
||||
.putInt(requiredInstructionOffsetReal)
|
||||
.putShort((short) 4)
|
||||
.putInt(patch);
|
||||
|
||||
return Arrays.copyOfRange(prePatch.array(), 1, 10);
|
||||
}
|
||||
private byte[] getPatch2(int offset) throws Exception{
|
||||
int requiredInstructionOffsetInternal = offset - 4;
|
||||
int requiredInstructionOffsetReal = requiredInstructionOffsetInternal + 0x100;
|
||||
final int patch = 0xE0031F2A; // mov w0, wzr
|
||||
logPrinter.print(BinToAsmPrinter.printSimplified(Integer.reverseBytes(patch), requiredInstructionOffsetInternal), EMsgType.NULL);
|
||||
|
||||
// Somehow IPS patches uses offsets written as big_endian (0.o) and bytes dat should be patched as LE.
|
||||
ByteBuffer prePatch = ByteBuffer.allocate(10).order(ByteOrder.BIG_ENDIAN)
|
||||
.putInt(requiredInstructionOffsetReal)
|
||||
.putShort((short) 4)
|
||||
.putInt(patch);
|
||||
|
||||
return Arrays.copyOfRange(prePatch.array(), 1, 10);
|
||||
}
|
||||
}
|
|
@ -1,185 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2022 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.fs;
|
||||
|
||||
import libKonogonka.KeyChainHolder;
|
||||
import libKonogonka.fs.NCA.NCAProvider;
|
||||
import nsusbloader.ModelControllers.CancellableRunnable;
|
||||
import nsusbloader.ModelControllers.ILogPrinter;
|
||||
import nsusbloader.ModelControllers.Log;
|
||||
import nsusbloader.NSLDataTypes.EModule;
|
||||
import nsusbloader.NSLDataTypes.EMsgType;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public class FsPatchMaker extends CancellableRunnable {
|
||||
private int THREADS_POOL_SIZE;
|
||||
private final ILogPrinter logPrinter;
|
||||
private final String pathToFirmware;
|
||||
private final String pathToKeysFile;
|
||||
private final String saveTo;
|
||||
|
||||
private File firmware;
|
||||
private KeyChainHolder keyChainHolder;
|
||||
private ExecutorService executorService;
|
||||
private List<String> ncaFilesList; // inside the folder
|
||||
|
||||
private boolean oneLinerStatus = false;
|
||||
|
||||
public FsPatchMaker(String pathToFirmware, String pathToKeysFile, String saveTo){
|
||||
this.logPrinter = Log.getPrinter(EModule.PATCHES);
|
||||
/*
|
||||
this.logPrinter = new ILogPrinter() {
|
||||
public void print(String message, EMsgType type) throws InterruptedException {}
|
||||
public void updateProgress(Double value) throws InterruptedException {}
|
||||
public void update(HashMap<String, File> nspMap, EFileStatus status) {}
|
||||
public void update(File file, EFileStatus status) {}
|
||||
public void updateOneLinerStatus(boolean status) {}
|
||||
public void close() {}
|
||||
};
|
||||
*/
|
||||
this.pathToFirmware = pathToFirmware;
|
||||
this.pathToKeysFile = pathToKeysFile;
|
||||
this.saveTo = saveTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
logPrinter.print("..:: Make FS Patches ::..", EMsgType.INFO);
|
||||
receiveFirmware();
|
||||
buildKeyChainHolder();
|
||||
receiveNcaFileNamesList();
|
||||
specifyThreadsPoolSize();
|
||||
createPool();
|
||||
executePool();
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
try{
|
||||
logPrinter.print(e.getMessage(), EMsgType.FAIL);
|
||||
} catch (Exception ignore){}
|
||||
}
|
||||
finally {
|
||||
logPrinter.updateOneLinerStatus(oneLinerStatus);
|
||||
logPrinter.close();
|
||||
}
|
||||
}
|
||||
private void receiveFirmware() throws Exception{
|
||||
logPrinter.print("Looking at firmware", EMsgType.INFO);
|
||||
this.firmware = new File(pathToFirmware);
|
||||
if (! firmware.exists())
|
||||
throw new Exception("Firmware directory does not exist " + pathToFirmware);
|
||||
}
|
||||
private void buildKeyChainHolder() throws Exception{
|
||||
logPrinter.print("Reading keys", EMsgType.INFO);
|
||||
this.keyChainHolder = new KeyChainHolder(pathToKeysFile, null);
|
||||
}
|
||||
private void receiveNcaFileNamesList() throws Exception{
|
||||
logPrinter.print("Collecting NCA files", EMsgType.INFO);
|
||||
String[] fileNamesArray = firmware.list(
|
||||
(File directory, String file) -> ( ! file.endsWith(".cnmt.nca") && file.endsWith(".nca")));
|
||||
ncaFilesList = Arrays.asList(Objects.requireNonNull(fileNamesArray));
|
||||
if (ncaFilesList.size() == 0)
|
||||
throw new Exception("No NCA files found in firmware folder");
|
||||
}
|
||||
private void specifyThreadsPoolSize(){
|
||||
THREADS_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors()+1, 4);
|
||||
THREADS_POOL_SIZE = Math.min(THREADS_POOL_SIZE, ncaFilesList.size());
|
||||
}
|
||||
|
||||
private void createPool() throws Exception{
|
||||
logPrinter.print("Creating sub-tasks pool", EMsgType.INFO);
|
||||
this.executorService = Executors.newFixedThreadPool(
|
||||
THREADS_POOL_SIZE,
|
||||
runnable -> {
|
||||
Thread thread = new Thread(runnable);
|
||||
thread.setDaemon(true);
|
||||
return thread;
|
||||
});
|
||||
}
|
||||
|
||||
private void executePool() throws Exception{ //TODO: FIX. Exceptions thrown only by logPrinter
|
||||
try {
|
||||
logPrinter.print("Executing sub-tasks pool", EMsgType.INFO);
|
||||
List<Future<List<NCAProvider>>> futuresResults = executorService.invokeAll(getSubTasksCollection());
|
||||
int counter = 0;
|
||||
for (Future<List<NCAProvider>> future : futuresResults){
|
||||
List<NCAProvider> ncaProviders = future.get();
|
||||
for (NCAProvider ncaProvider : ncaProviders) {
|
||||
makePatches(ncaProvider);
|
||||
if (++counter > 1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
executorService.shutdown();
|
||||
}
|
||||
catch (InterruptedException ie){
|
||||
executorService.shutdownNow();
|
||||
boolean interruptedSuccessfully = false;
|
||||
try {
|
||||
interruptedSuccessfully = executorService.awaitTermination(20, TimeUnit.SECONDS);
|
||||
}
|
||||
catch (InterruptedException awaitInterrupt){
|
||||
logPrinter.print("Force interrupting task...", EMsgType.WARNING);
|
||||
}
|
||||
logPrinter.print("Task interrupted "+(interruptedSuccessfully?"successfully":"with some issues"), EMsgType.WARNING);
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
logPrinter.print("Task failed: "+e.getMessage(), EMsgType.FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
private void makePatches(NCAProvider ncaProvider) throws Exception{
|
||||
final File foundFile = ncaProvider.getFile();
|
||||
logPrinter.print(String.format("File found: .."+File.separator+"%s"+File.separator+"%s",
|
||||
foundFile.getParentFile().getName(), foundFile.getName()), EMsgType.INFO);
|
||||
new FsPatch(ncaProvider, saveTo, keyChainHolder, logPrinter);
|
||||
oneLinerStatus = true;
|
||||
}
|
||||
private List<Callable<List<NCAProvider>>> getSubTasksCollection() throws Exception{
|
||||
logPrinter.print("Forming sub-tasks collection", EMsgType.INFO);
|
||||
List<Callable<List<NCAProvider>>> subTasks = new ArrayList<>();
|
||||
|
||||
int ncaPerThreadAmount = ncaFilesList.size() / THREADS_POOL_SIZE;
|
||||
Iterator<String> iterator = ncaFilesList.listIterator();
|
||||
|
||||
for (int i = 1; i < THREADS_POOL_SIZE; i++){
|
||||
Callable<List<NCAProvider>> task = new FsNcaSearchTask(getNextSet(iterator, ncaPerThreadAmount));
|
||||
subTasks.add(task);
|
||||
}
|
||||
int leftovers = ncaFilesList.size() % THREADS_POOL_SIZE;
|
||||
Callable<List<NCAProvider>> task = new FsNcaSearchTask(getNextSet(iterator, ncaPerThreadAmount+leftovers));
|
||||
subTasks.add(task);
|
||||
return subTasks;
|
||||
}
|
||||
private List<NCAProvider> getNextSet(Iterator<String> iterator, int amount) throws Exception{
|
||||
List<NCAProvider> ncas = new ArrayList<>();
|
||||
for (int j = 0; j < amount; j++){
|
||||
String ncaFileName = iterator.next();
|
||||
File nca = new File(firmware.getAbsolutePath()+File.separator+ncaFileName);
|
||||
NCAProvider provider = new NCAProvider(nca, keyChainHolder.getRawKeySet());
|
||||
ncas.add(provider);
|
||||
}
|
||||
return ncas;
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2023 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.fs.finders;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import nsusbloader.AppPreferences;
|
||||
import nsusbloader.Utilities.patches.AHeuristic;
|
||||
import nsusbloader.Utilities.patches.BinToAsmPrinter;
|
||||
import nsusbloader.Utilities.patches.SimplyFind;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class HeuristicFs1 extends AHeuristic {
|
||||
private static final String PATTERN = AppPreferences.getInstance().getPatchPattern("FS", 1, 0); // TBZ
|
||||
|
||||
private final byte[] where;
|
||||
private final List<Integer> findings;
|
||||
|
||||
HeuristicFs1(byte[] where) {
|
||||
this.where = where;
|
||||
this.findings = new ArrayList<>();
|
||||
SimplyFind simplyfind = new SimplyFind(PATTERN, where);
|
||||
simplyfind.getResults().forEach(var -> findings.add(var + 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFound() {
|
||||
return findings.size() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wantLessEntropy() {
|
||||
return findings.size() > 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() throws Exception {
|
||||
if (findings.isEmpty())
|
||||
throw new Exception("Nothing found");
|
||||
if (findings.size() > 1)
|
||||
throw new Exception("Too many offsets");
|
||||
return findings.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setOffsetsNearby(int offsetNearby) {
|
||||
findings.removeIf(offset -> {
|
||||
if (offset > offsetNearby)
|
||||
return !(offset < offsetNearby - 0xffff);
|
||||
return !(offset > offsetNearby - 0xffff);
|
||||
});
|
||||
return isFound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetails() {
|
||||
int offsetInternal = findings.get(0) - 4;
|
||||
int firstExpression = Converter.getLEint(where, offsetInternal);
|
||||
int conditionalJumpLocation = offsetInternal + (firstExpression >> 5 & 0x3fff) * 4;
|
||||
|
||||
int secondExpressionsPairElement1 = Converter.getLEint(where, conditionalJumpLocation);
|
||||
int secondExpressionsPairElement2 = Converter.getLEint(where, conditionalJumpLocation + 4);
|
||||
|
||||
return BinToAsmPrinter.printSimplified(firstExpression, offsetInternal) +
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(where, offsetInternal + 4), offsetInternal + 4) +
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(where, offsetInternal + 8), offsetInternal + 8) +
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(where, offsetInternal + 12), offsetInternal + 12) +
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(where, offsetInternal + 16), offsetInternal + 16) +
|
||||
"...\n" +
|
||||
BinToAsmPrinter.printSimplified(secondExpressionsPairElement1, conditionalJumpLocation) +
|
||||
BinToAsmPrinter.printSimplified(secondExpressionsPairElement2, conditionalJumpLocation + 4);
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2023 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.fs.finders;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import nsusbloader.AppPreferences;
|
||||
import nsusbloader.Utilities.patches.AHeuristic;
|
||||
import nsusbloader.Utilities.patches.BinToAsmPrinter;
|
||||
import nsusbloader.Utilities.patches.SimplyFind;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class HeuristicFs2 extends AHeuristic {
|
||||
private static final String PATTERN = AppPreferences.getInstance().getPatchPattern("FS", 2, 0);
|
||||
|
||||
private final byte[] where;
|
||||
private final List<Integer> findings;
|
||||
|
||||
HeuristicFs2(byte[] where){
|
||||
this.where = where;
|
||||
this.findings = new ArrayList<>();
|
||||
SimplyFind simplyfind = new SimplyFind(PATTERN, where);
|
||||
simplyfind.getResults().forEach(var -> findings.add(var + 4));
|
||||
|
||||
if(findings.size() < 2)
|
||||
return;
|
||||
|
||||
this.findings.removeIf(this::dropStep1);
|
||||
}
|
||||
// All matches are somewhere in 0x6xxxx-0x7xxxx, then let's just limit search field by 0x80000
|
||||
private boolean dropStep1(int offsetOfPatternFound){
|
||||
return (offsetOfPatternFound > 0x80000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFound(){
|
||||
return findings.size() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wantLessEntropy(){
|
||||
return findings.size() > 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOffset() throws Exception{
|
||||
if(findings.isEmpty())
|
||||
throw new Exception("Nothing found");
|
||||
if (findings.size() > 1)
|
||||
throw new Exception("Too many offsets");
|
||||
return findings.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setOffsetsNearby(int offsetNearby) {
|
||||
findings.removeIf(offset -> {
|
||||
if (offset > offsetNearby)
|
||||
return ! (offset < offsetNearby - 0xffff);
|
||||
return ! (offset > offsetNearby - 0xffff);
|
||||
});
|
||||
return isFound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetails(){
|
||||
int offsetInternal = findings.get(0) - 4;
|
||||
int firstExpression = Converter.getLEint(where, offsetInternal);
|
||||
int conditionalJumpLocation = ((firstExpression & 0x3ffffff) * 4 + offsetInternal) & 0xfffff;
|
||||
int secondExpressionsPairElement1 = Converter.getLEint(where, conditionalJumpLocation);
|
||||
int secondExpressionsPairElement2 = Converter.getLEint(where, conditionalJumpLocation+4);
|
||||
|
||||
return BinToAsmPrinter.printSimplified(firstExpression, offsetInternal) +
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(where, offsetInternal + 4), offsetInternal + 4) +
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(where, offsetInternal + 8), offsetInternal + 8) +
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(where, offsetInternal + 12), offsetInternal + 12) +
|
||||
"...\n" +
|
||||
BinToAsmPrinter.printSimplified(secondExpressionsPairElement1, conditionalJumpLocation) +
|
||||
BinToAsmPrinter.printSimplified(secondExpressionsPairElement2, conditionalJumpLocation + 4);
|
||||
}
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2023 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.fs.finders;
|
||||
|
||||
import nsusbloader.Utilities.patches.AHeuristic;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class HeuristicFsWizard {
|
||||
private final List<AHeuristic> all;
|
||||
private final List<AHeuristic> found;
|
||||
private final List<AHeuristic> wantLessEntropy;
|
||||
|
||||
private final StringBuilder errorsAndNotes;
|
||||
|
||||
private int offset1 = -1;
|
||||
private int offset2 = -1;
|
||||
|
||||
public HeuristicFsWizard(byte[] where) throws Exception{
|
||||
this.errorsAndNotes = new StringBuilder();
|
||||
|
||||
this.all = Arrays.asList(
|
||||
new HeuristicFs1(where),
|
||||
new HeuristicFs2(where)
|
||||
);
|
||||
|
||||
this.found = all.stream()
|
||||
.filter(AHeuristic::isFound)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (found.isEmpty())
|
||||
throw new Exception("Nothing found!");
|
||||
|
||||
this.wantLessEntropy = all.stream()
|
||||
.filter(AHeuristic::wantLessEntropy)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
shareOffsetsWithEachOther();
|
||||
|
||||
assignOffset1();
|
||||
assignOffset2();
|
||||
}
|
||||
|
||||
private void shareOffsetsWithEachOther(){
|
||||
for (AHeuristic es : wantLessEntropy) {
|
||||
if (shareWithNext(es))
|
||||
return;
|
||||
}
|
||||
}
|
||||
private boolean shareWithNext(AHeuristic es){
|
||||
try {
|
||||
for (AHeuristic foundEs : found) {
|
||||
if (es.setOffsetsNearby(foundEs.getOffset())) {
|
||||
found.add(es);
|
||||
wantLessEntropy.remove(es);
|
||||
shareOffsetsWithEachOther();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e){ e.printStackTrace(); }
|
||||
return false;
|
||||
}
|
||||
|
||||
private void assignOffset1(){
|
||||
try {
|
||||
offset1 = all.get(0).getOffset();
|
||||
}
|
||||
catch (Exception e){ errorsAndNotes.append(e.getLocalizedMessage()).append("\n"); }
|
||||
}
|
||||
private void assignOffset2(){
|
||||
try {
|
||||
offset2 = all.get(1).getOffset();
|
||||
}
|
||||
catch (Exception e){ errorsAndNotes.append(e.getLocalizedMessage()).append("\n"); }
|
||||
}
|
||||
|
||||
public String getErrorsAndNotes(){
|
||||
return errorsAndNotes.toString();
|
||||
}
|
||||
|
||||
public String getDebug(){
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (all.get(0).isFound()){
|
||||
builder.append("\t\t-=== 1 ===-\n");
|
||||
builder.append(all.get(0).getDetails());
|
||||
}
|
||||
if (all.get(1).isFound()){
|
||||
builder.append("\t\t-=== 2 ===-\n");
|
||||
builder.append(all.get(1).getDetails());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public int getOffset1() { return offset1; }
|
||||
public int getOffset2() { return offset2; }
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
Copyright 2019-2023 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.loader;
|
||||
|
||||
import nsusbloader.ModelControllers.ILogPrinter;
|
||||
import nsusbloader.NSLDataTypes.EMsgType;
|
||||
import nsusbloader.Utilities.patches.MalformedIniFileException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
|
||||
public class LoaderIniMaker {
|
||||
private static final String FILE_HEADER_TEXT = "# UTF-8\n" +
|
||||
"# A KIP section is [kip1_name:sha256_hex_8bytes]\n" +
|
||||
"# A patchset is .patch_name=kip_section_dec:offset_hex_0x:length_hex_0x:src_data_hex,dst_data_hex\n" +
|
||||
"# _dec: 1 char decimal | _hex_0x: max u32 prefixed with 0x | _hex: hex array.\n" +
|
||||
"# Kip1 section decimals: TEXT: 0, RODATA: 1, DATA: 2.\n"; // Sending good vibes to Mr. ITotalJustice
|
||||
|
||||
private final ILogPrinter logPrinter;
|
||||
private final String saveToLocation;
|
||||
private final int offset;
|
||||
|
||||
private String sectionDeclaration;
|
||||
private String patchSet;
|
||||
|
||||
LoaderIniMaker(ILogPrinter logPrinter,
|
||||
String saveToLocation,
|
||||
int foundOffset,
|
||||
String patchName) throws Exception{
|
||||
this.logPrinter = logPrinter;
|
||||
this.saveToLocation = saveToLocation;
|
||||
this.offset = foundOffset + 6;
|
||||
|
||||
mkDirs();
|
||||
makeSectionDeclaration(patchName);
|
||||
makePatchSet1();
|
||||
writeFile();
|
||||
}
|
||||
|
||||
private void mkDirs(){
|
||||
File parentFolder = new File(saveToLocation + File.separator + "bootloader");
|
||||
parentFolder.mkdirs();
|
||||
}
|
||||
|
||||
private void makeSectionDeclaration(String patchName){
|
||||
sectionDeclaration = "[Loader:"+patchName.substring(0, 16)+"]";
|
||||
}
|
||||
|
||||
private void makePatchSet1(){
|
||||
patchSet = String.format(".nosigchk=0:0x%02X:0x1:01,00", offset);
|
||||
}
|
||||
|
||||
private void writeFile() throws Exception{
|
||||
final String iniLocation = saveToLocation + File.separator + "bootloader" + File.separator + "patches.ini";
|
||||
final Path iniLocationPath = Paths.get(iniLocation);
|
||||
|
||||
boolean iniNotExists = Files.notExists(iniLocationPath);
|
||||
|
||||
try (RandomAccessFile ini = new RandomAccessFile(iniLocation, "rw")){
|
||||
if (iniNotExists)
|
||||
ini.writeBytes(FILE_HEADER_TEXT);
|
||||
else {
|
||||
String line;
|
||||
while ((line = ini.readLine()) != null){
|
||||
if (! line.startsWith(sectionDeclaration))
|
||||
continue;
|
||||
|
||||
String expression = ini.readLine();
|
||||
|
||||
if (expression == null || ! expression.startsWith(patchSet))
|
||||
throw new MalformedIniFileException("Somewhere near "+ini.getFilePointer());
|
||||
|
||||
return; // Ini file already contains correct information regarding patch file we made.
|
||||
}
|
||||
}
|
||||
|
||||
ini.writeBytes("\n#Loader (Atmosphere)\n");
|
||||
ini.writeBytes(sectionDeclaration);
|
||||
ini.writeBytes("\n");
|
||||
|
||||
ini.writeBytes(patchSet);
|
||||
ini.writeBytes("\n");
|
||||
}
|
||||
catch (MalformedIniFileException e){
|
||||
e.printStackTrace();
|
||||
logPrinter.print(
|
||||
"Existing patches.ini file is malformed or contains incorrect (outdated) information regarding current patch.\n" +
|
||||
"It's now saved at "+iniLocation+".OLD\n" +
|
||||
"New patches.ini file created instead.", EMsgType.WARNING);
|
||||
Files.move(iniLocationPath, Paths.get(iniLocation+".OLD"),
|
||||
StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
|
||||
writeFile();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2023 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
---
|
||||
Based on https://github.com/mrdude2478/IPS_Patch_Creator patch script made by GBATemp member MrDude.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.loader;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import libKonogonka.fs.other.System2.ini1.KIP1Provider;
|
||||
import nsusbloader.ModelControllers.ILogPrinter;
|
||||
import nsusbloader.NSLDataTypes.EMsgType;
|
||||
import nsusbloader.Utilities.patches.BinToAsmPrinter;
|
||||
import nsusbloader.Utilities.patches.SimplyFind;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class LoaderPatch {
|
||||
private static final byte[] HEADER = "PATCH".getBytes(StandardCharsets.US_ASCII);
|
||||
private static final byte[] FOOTER = "EOF".getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
private static final String ATMOSPHERE_NEW_PATTERN = "01C0BE121F00016B";
|
||||
//private static final String ATMOSPHERE_OLD_PATTERN = "003C00121F280071"; Must be patched using different (to current implementation) code
|
||||
|
||||
private final String saveToLocation;
|
||||
private final ILogPrinter logPrinter;
|
||||
|
||||
private String patchName;
|
||||
private byte[] _textSection;
|
||||
|
||||
private int offset;
|
||||
|
||||
LoaderPatch(KIP1Provider loaderProvider,
|
||||
String saveToLocation,
|
||||
ILogPrinter logPrinter) throws Exception{
|
||||
this.saveToLocation = saveToLocation;
|
||||
this.logPrinter = logPrinter;
|
||||
|
||||
getPatchName(loaderProvider);
|
||||
getTextSection(loaderProvider);
|
||||
findOffset();
|
||||
mkDirs();
|
||||
writeFile();
|
||||
new LoaderIniMaker(logPrinter, saveToLocation, offset, patchName);
|
||||
}
|
||||
private void getPatchName(KIP1Provider kip1Provider) throws Exception{
|
||||
int kip1EncryptedSize = (int) kip1Provider.getSize();
|
||||
byte[] kip1EncryptedRaw = new byte[kip1EncryptedSize];
|
||||
|
||||
try (BufferedInputStream kip1ProviderStream = kip1Provider.getStreamProducer().produce()) {
|
||||
if (kip1EncryptedSize != kip1ProviderStream.read(kip1EncryptedRaw))
|
||||
throw new Exception("Unencrypted FS KIP1 read failure");
|
||||
}
|
||||
|
||||
byte[] sha256ofKip1 = MessageDigest.getInstance("SHA-256").digest(kip1EncryptedRaw);
|
||||
patchName = Converter.byteArrToHexStringAsLE(sha256ofKip1, true) + ".ips";
|
||||
}
|
||||
private void getTextSection(KIP1Provider kip1Provider) throws Exception{
|
||||
_textSection = kip1Provider.getAsDecompressed().getTextRaw();
|
||||
}
|
||||
private void findOffset() throws Exception{
|
||||
SimplyFind simplyFind = new SimplyFind(ATMOSPHERE_NEW_PATTERN, _textSection); // Atm 13+
|
||||
if (simplyFind.getResults().size() == 0)
|
||||
throw new Exception("Offset not found");
|
||||
|
||||
offset = simplyFind.getResults().get(0);
|
||||
|
||||
if (offset <= 0)
|
||||
throw new Exception("Found offset is incorrect");
|
||||
|
||||
for (int i = 0; i < simplyFind.getResults().size(); i++) {
|
||||
int offsetInternal = simplyFind.getResults().get(i) + 4;
|
||||
logPrinter.print("Only first (#1) found record will be patched!", EMsgType.INFO);
|
||||
logPrinter.print("Found #" + (i+1) +"\n"+
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(_textSection, offsetInternal), offsetInternal) +
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(_textSection, offsetInternal + 4), offsetInternal + 4) +
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(_textSection, offsetInternal + 8), offsetInternal + 8) +
|
||||
BinToAsmPrinter.printSimplified(Converter.getLEint(_textSection, offsetInternal + 12), offsetInternal + 12),
|
||||
EMsgType.NULL);
|
||||
}
|
||||
}
|
||||
private void mkDirs(){
|
||||
File parentFolder = new File(saveToLocation + File.separator +
|
||||
"atmosphere" + File.separator + "kip_patches" + File.separator + "loader_patches");
|
||||
parentFolder.mkdirs();
|
||||
}
|
||||
|
||||
private void writeFile() throws Exception{
|
||||
String patchFileLocation = saveToLocation + File.separator +
|
||||
"atmosphere" + File.separator + "kip_patches" + File.separator + "loader_patches" + File.separator + patchName;
|
||||
|
||||
ByteBuffer handyFsPatch = ByteBuffer.allocate(0x100).order(ByteOrder.LITTLE_ENDIAN);
|
||||
handyFsPatch.put(HEADER);
|
||||
handyFsPatch.put(getPatch1(offset));
|
||||
handyFsPatch.put(FOOTER);
|
||||
|
||||
byte[] fsPatch = new byte[handyFsPatch.position()];
|
||||
((Buffer) handyFsPatch).rewind();
|
||||
handyFsPatch.get(fsPatch);
|
||||
|
||||
try (BufferedOutputStream stream = new BufferedOutputStream(
|
||||
Files.newOutputStream(Paths.get(patchFileLocation)))){
|
||||
stream.write(fsPatch);
|
||||
}
|
||||
logPrinter.print("Patch created at "+patchFileLocation, EMsgType.PASS);
|
||||
}
|
||||
|
||||
private byte[] getPatch1(int offset) throws Exception{
|
||||
int requiredInstructionOffsetInternal = offset + 6;
|
||||
int requiredInstructionOffsetReal = requiredInstructionOffsetInternal + 0x100;
|
||||
final byte[] patch = new byte[]{0x00, 0x01, 0x00};
|
||||
|
||||
int instructionPatched = Converter.getLEint(_textSection, offset + 4) & 0xff00ffff;
|
||||
|
||||
logPrinter.print("Patch will be applied", EMsgType.PASS);
|
||||
logPrinter.print(BinToAsmPrinter.printSimplified(instructionPatched, offset+4), EMsgType.NULL);
|
||||
|
||||
ByteBuffer prePatch = ByteBuffer.allocate(7).order(ByteOrder.BIG_ENDIAN)
|
||||
.putInt(requiredInstructionOffsetReal)
|
||||
.put(patch);
|
||||
|
||||
return Arrays.copyOfRange(prePatch.array(), 1, 7);
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
/*
|
||||
Copyright 2018-2022 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.Utilities.patches.loader;
|
||||
|
||||
import libKonogonka.Converter;
|
||||
import libKonogonka.fs.other.System2.ini1.KIP1Provider;
|
||||
import nsusbloader.ModelControllers.CancellableRunnable;
|
||||
import nsusbloader.ModelControllers.ILogPrinter;
|
||||
import nsusbloader.ModelControllers.Log;
|
||||
import nsusbloader.NSLDataTypes.EModule;
|
||||
import nsusbloader.NSLDataTypes.EMsgType;
|
||||
import nsusbloader.Utilities.patches.SimplyFind;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
|
||||
public class LoaderPatchMaker extends CancellableRunnable {
|
||||
|
||||
private final ILogPrinter logPrinter;
|
||||
private final String atmosphereLocation;
|
||||
private final String saveTo;
|
||||
|
||||
private String package3Location;
|
||||
private KIP1Provider loaderProvider;
|
||||
|
||||
private boolean oneLinerStatus = false;
|
||||
|
||||
public LoaderPatchMaker(String atmosphereLocation, String saveTo){
|
||||
this.logPrinter = Log.getPrinter(EModule.PATCHES);
|
||||
/*
|
||||
this.logPrinter = new ILogPrinter() {
|
||||
public void print(String message, EMsgType type) throws InterruptedException {}
|
||||
public void updateProgress(Double value) throws InterruptedException {}
|
||||
public void update(HashMap<String, File> nspMap, EFileStatus status) {}
|
||||
public void update(File file, EFileStatus status) {}
|
||||
public void updateOneLinerStatus(boolean status) {}
|
||||
public void close() {}
|
||||
};
|
||||
//*/
|
||||
this.atmosphereLocation = atmosphereLocation;
|
||||
this.saveTo = saveTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
logPrinter.print("..:: Make Loader Patches ::..", EMsgType.INFO);
|
||||
checkPackage3();
|
||||
createLoaderKip1Provider();
|
||||
makePatches();
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
try{
|
||||
logPrinter.print(e.getMessage(), EMsgType.FAIL);
|
||||
} catch (Exception ignore){}
|
||||
}
|
||||
finally {
|
||||
logPrinter.updateOneLinerStatus(oneLinerStatus);
|
||||
logPrinter.close();
|
||||
}
|
||||
}
|
||||
private void checkPackage3() throws Exception{
|
||||
logPrinter.print("Looking at Atmosphere", EMsgType.INFO);
|
||||
if (Files.notExists(Paths.get(atmosphereLocation)))
|
||||
throw new Exception("Atmosphere directory does not exist at " + atmosphereLocation);
|
||||
|
||||
package3Location = atmosphereLocation +File.separator+"package3";
|
||||
if (Files.exists(Paths.get(package3Location)))
|
||||
return;
|
||||
|
||||
package3Location = atmosphereLocation +File.separator+"fusee-secondary.bin";
|
||||
if (Files.notExists(Paths.get(package3Location)))
|
||||
throw new Exception("package3 / fusee-secondary.bin file not found at " + atmosphereLocation);
|
||||
}
|
||||
|
||||
private void createLoaderKip1Provider() throws Exception{
|
||||
Path package3Path = Paths.get(package3Location);
|
||||
|
||||
try (BufferedInputStream stream = new BufferedInputStream(Files.newInputStream(package3Path))) {
|
||||
byte[] data = new byte[0x400];
|
||||
if (0x400 != stream.read(data))
|
||||
throw new Exception("Failed to read first 0x400 bytes of package3 / fusee-secondary file.");
|
||||
|
||||
SimplyFind simplyFind = new SimplyFind(".6f61646572", data); // eq. '.oader'
|
||||
List<Integer> results = simplyFind.getResults();
|
||||
if (results.size() == 0)
|
||||
throw new Exception("Failed to find 'Loader' offset at package3 / fusee-secondary file.");
|
||||
|
||||
int offset = results.get(0);
|
||||
int kip1Offset = Converter.getLEint(data, offset - 0x10);
|
||||
int kip1Size = Converter.getLEint(data, offset - 0xC);
|
||||
|
||||
loaderProvider = new KIP1Provider(package3Location, kip1Offset);
|
||||
|
||||
if (kip1Size != loaderProvider.getSize())
|
||||
throw new Exception("Incorrect calculations for KIP1. PK31 value: "+kip1Size+"KIP1Provider value: "+loaderProvider.getSize());
|
||||
logPrinter.print("Loader KIP1 found", EMsgType.PASS);
|
||||
}
|
||||
}
|
||||
private void makePatches() throws Exception{
|
||||
new LoaderPatch(loaderProvider, saveTo, logPrinter);
|
||||
oneLinerStatus = true;
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ public class CommandLineInterface {
|
|||
}
|
||||
|
||||
final Options cliOptions = createCliOptions();
|
||||
|
||||
CommandLineParser cliParser = new DefaultParser();
|
||||
try{
|
||||
CommandLine cli = cliParser.parse(cliOptions, args);
|
||||
|
@ -67,11 +68,6 @@ public class CommandLineInterface {
|
|||
new GoldLeafCli(arguments);
|
||||
return;
|
||||
}
|
||||
if (cli.hasOption("experimental")){
|
||||
final String[] arguments = cli.getOptionValues("experimental");
|
||||
new ExperimentalCli(arguments);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
if (cli.hasOption("x") || cli.hasOption("nxdt")){
|
||||
final String[] arguments = cli.getOptionValues("nxdt");
|
||||
|
@ -158,12 +154,6 @@ public class CommandLineInterface {
|
|||
.hasArgs()
|
||||
.argName("...")
|
||||
.build();
|
||||
final Option experimentalOption = Option.builder()
|
||||
.longOpt("experimental")
|
||||
.desc("Enable testing and experimental functions")
|
||||
.hasArgs()
|
||||
.argName("y|n")
|
||||
.build();
|
||||
/* nxdumptool */
|
||||
/*
|
||||
final Option nxdtOption = Option.builder("x")
|
||||
|
@ -194,7 +184,6 @@ public class CommandLineInterface {
|
|||
group.addOption(helpOption);
|
||||
group.addOption(tinfoilOption);
|
||||
group.addOption(glOption);
|
||||
group.addOption(experimentalOption);
|
||||
//group.addOption(nxdtOption);
|
||||
group.addOption(splitOption);
|
||||
group.addOption(mergeOption);
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
Copyright 2019-2023 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
NS-USBloader 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.
|
||||
|
||||
NS-USBloader 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 NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package nsusbloader.cli;
|
||||
|
||||
import nsusbloader.AppPreferences;
|
||||
|
||||
public class ExperimentalCli {
|
||||
ExperimentalCli(String[] arguments) throws IncorrectSetupException{
|
||||
if (arguments == null || arguments.length == 0)
|
||||
throw new IncorrectSetupException("No arguments.\nShould be 'y' or 'n'");
|
||||
|
||||
if (arguments.length > 1)
|
||||
throw new IncorrectSetupException("Too many arguments.\nShould be 'y' or 'n' only");
|
||||
|
||||
String arg = arguments[0].toLowerCase().substring(0, 1);
|
||||
|
||||
if (arg.equals("y")) {
|
||||
AppPreferences.getInstance().setPatchesTabInvisible(false);
|
||||
System.out.println("Experimental functions enabled");
|
||||
return;
|
||||
}
|
||||
if (arg.equals("n")) {
|
||||
AppPreferences.getInstance().setPatchesTabInvisible(true);
|
||||
System.out.println("Experimental functions disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
throw new IncorrectSetupException("Incorrect arguments.\nCould be 'y' or 'n' only");
|
||||
}
|
||||
}
|
|
@ -34,7 +34,7 @@ public class GoldLeafCli {
|
|||
|
||||
private int parseFileSince = 1;
|
||||
|
||||
GoldLeafCli(String[] arguments) throws InterruptedException, IncorrectSetupException{
|
||||
public GoldLeafCli(String[] arguments) throws InterruptedException, IncorrectSetupException{
|
||||
this.arguments = arguments;
|
||||
|
||||
checkArguments();
|
||||
|
@ -43,7 +43,7 @@ public class GoldLeafCli {
|
|||
runGoldLeafBackend();
|
||||
}
|
||||
|
||||
private void checkArguments() throws IncorrectSetupException{
|
||||
public void checkArguments() throws IncorrectSetupException{
|
||||
if (arguments == null || arguments.length == 0) {
|
||||
throw new IncorrectSetupException("No arguments.\n" +
|
||||
"Try 'ns-usbloader -g help' for more information.");
|
||||
|
@ -75,7 +75,7 @@ public class GoldLeafCli {
|
|||
private String getGlSupportedVersions(){
|
||||
StringBuilder builder = new StringBuilder("Supported versions: \n");
|
||||
|
||||
for (String a : AppPreferences.GOLDLEAF_SUPPORTED_VERSIONS){
|
||||
for (String a : AppPreferences.goldleafSupportedVersions){
|
||||
builder.append("\t");
|
||||
builder.append(a);
|
||||
builder.append("\n");
|
||||
|
@ -83,7 +83,7 @@ public class GoldLeafCli {
|
|||
return builder.toString();
|
||||
}
|
||||
|
||||
private void parseGoldLeafVersion() throws IncorrectSetupException{
|
||||
public void parseGoldLeafVersion() throws IncorrectSetupException{
|
||||
String argument1 = arguments[0];
|
||||
|
||||
if (! argument1.startsWith("ver=")) {
|
||||
|
@ -98,7 +98,7 @@ public class GoldLeafCli {
|
|||
"Try 'ns-usbloader -g help' for more information.");
|
||||
}
|
||||
|
||||
for (String version : AppPreferences.GOLDLEAF_SUPPORTED_VERSIONS){
|
||||
for (String version : AppPreferences.goldleafSupportedVersions){
|
||||
if (version.equals(goldLeafVersion))
|
||||
return;
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ public class GoldLeafCli {
|
|||
getGlSupportedVersions());
|
||||
}
|
||||
|
||||
private void parseFilesArguments() throws IncorrectSetupException{
|
||||
public void parseFilesArguments() throws IncorrectSetupException{
|
||||
filesList = new ArrayList<>();
|
||||
File file;
|
||||
|
||||
|
@ -123,7 +123,7 @@ public class GoldLeafCli {
|
|||
}
|
||||
}
|
||||
|
||||
private void runGoldLeafBackend() throws InterruptedException {
|
||||
public void runGoldLeafBackend() throws InterruptedException {
|
||||
Runnable task = new UsbCommunications(filesList,
|
||||
"GoldLeaf"+goldLeafVersion,
|
||||
filterForNsp);
|
||||
|
|
|
@ -27,7 +27,7 @@ public class NxdtCli {
|
|||
private final String[] arguments;
|
||||
private String saveTo;
|
||||
|
||||
NxdtCli(String[] arguments) throws InterruptedException, IncorrectSetupException{
|
||||
public NxdtCli(String[] arguments) throws InterruptedException, IncorrectSetupException{
|
||||
this.arguments = arguments;
|
||||
parseArgument();
|
||||
runBackend();
|
||||
|
|
|
@ -29,7 +29,7 @@ public class TinfoilUsbCli {
|
|||
private final String[] arguments;
|
||||
private List<File> filesList;
|
||||
|
||||
TinfoilUsbCli(String[] arguments) throws InterruptedException, IncorrectSetupException{
|
||||
public TinfoilUsbCli(String[] arguments) throws InterruptedException, IncorrectSetupException{
|
||||
this.arguments = arguments;
|
||||
checkArguments();
|
||||
parseFilesArguments();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
Copyright 2019-2022 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -933,7 +933,7 @@ class GoldLeaf_010 extends TransferModule {
|
|||
private boolean selectFile(){
|
||||
File selectedFile = CompletableFuture.supplyAsync(() -> {
|
||||
FileChooser fChooser = new FileChooser();
|
||||
fChooser.setTitle(MediatorControl.INSTANCE.getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION
|
||||
fChooser.setTitle(MediatorControl.getInstance().getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION
|
||||
fChooser.setInitialDirectory(new File(System.getProperty("user.home")));// TODO: Consider fixing; not a priority.
|
||||
fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*"));
|
||||
return fChooser.showOpenDialog(null); // Leave as is for now.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -918,7 +918,7 @@ class GoldLeaf_07 extends TransferModule {
|
|||
private boolean selectFile(){
|
||||
File selectedFile = CompletableFuture.supplyAsync(() -> {
|
||||
FileChooser fChooser = new FileChooser();
|
||||
fChooser.setTitle(MediatorControl.INSTANCE.getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION
|
||||
fChooser.setTitle(MediatorControl.getInstance().getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION
|
||||
fChooser.setInitialDirectory(new File(System.getProperty("user.home"))); // TODO: Consider fixing; not a prio.
|
||||
fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*"));
|
||||
return fChooser.showOpenDialog(null); // Leave as is for now.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019-2024 Dmitry Isaenko
|
||||
Copyright 2019-2020 Dmitry Isaenko
|
||||
|
||||
This file is part of NS-USBloader.
|
||||
|
||||
|
@ -941,7 +941,7 @@ class GoldLeaf_08 extends TransferModule {
|
|||
private boolean selectFile(){
|
||||
File selectedFile = CompletableFuture.supplyAsync(() -> {
|
||||
FileChooser fChooser = new FileChooser();
|
||||
fChooser.setTitle(MediatorControl.INSTANCE.getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION
|
||||
fChooser.setTitle(MediatorControl.getInstance().getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION
|
||||
fChooser.setInitialDirectory(new File(System.getProperty("user.home")));// TODO: Consider fixing; not a prio.
|
||||
fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*"));
|
||||
return fChooser.showOpenDialog(null); // Leave as is for now.
|
||||
|
|
|
@ -66,7 +66,7 @@ public class UsbCommunications extends CancellableRunnable {
|
|||
case "TinFoil":
|
||||
module = new TinFoil(handler, nspMap, this, logPrinter);
|
||||
break;
|
||||
case "GoldLeafv0.10+":
|
||||
case "GoldLeafv0.10":
|
||||
module = new GoldLeaf_010(handler, nspMap, this, logPrinter, nspFilterForGl);
|
||||
break;
|
||||
case "GoldLeafv0.8-0.9":
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.control.Spinner?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
|
||||
<AnchorPane xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.FontSettingsController">
|
||||
<children>
|
||||
<VBox layoutX="344.0" layoutY="132.0" prefHeight="200.0" prefWidth="100.0" spacing="5.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<ListView fx:id="fontsLv" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS" />
|
||||
<Text fx:id="exampleText" strokeType="OUTSIDE" strokeWidth="0.0" />
|
||||
<HBox alignment="CENTER_RIGHT" spacing="5.0">
|
||||
<children>
|
||||
<Label text="%fontSize" wrapText="true" />
|
||||
<Spinner fx:id="fontSizeSpinner" minWidth="100.0" />
|
||||
<Pane HBox.hgrow="ALWAYS" />
|
||||
<Button fx:id="resetBtn" mnemonicParsing="false" text="%btn_ResetToDefaults">
|
||||
<HBox.margin>
|
||||
<Insets right="5.0" />
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
<Button fx:id="cancelBtn" mnemonicParsing="false" text="%btn_Cancel" wrapText="true" />
|
||||
<Button fx:id="applyBtn" mnemonicParsing="false" styleClass="buttonUp" text="%btn_Select" wrapText="true" />
|
||||
</children>
|
||||
</HBox>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</VBox>
|
||||
</children>
|
||||
</AnchorPane>
|
|
@ -55,7 +55,7 @@
|
|||
<Insets />
|
||||
</HBox.margin>
|
||||
</Button>
|
||||
<Button fx:id="selectSplitBtn" contentDisplay="TOP" mnemonicParsing="false" prefHeight="60.0" text="%btn_OpenSplitFile">
|
||||
<Button fx:id="selectSplitNspBtn" contentDisplay="TOP" mnemonicParsing="false" prefHeight="60.0" text="%btn_OpenSplitFile">
|
||||
<graphic>
|
||||
<SVGPath content="M 2.4003906 2 C 1.0683906 2 0 3.1125 0 4.5 L 0 19.5 A 2.4 2.5 0 0 0 2.4003906 22 L 21.599609 22 A 2.4 2.5 0 0 0 24 19.5 L 24 7 C 24 5.6125 22.919609 4.5 21.599609 4.5 L 12 4.5 L 9.5996094 2 L 2.4003906 2 z M 13.193359 10.962891 C 14.113498 10.962891 14.814236 11.348741 15.296875 12.123047 C 15.779514 12.89388 16.021484 13.935113 16.021484 15.244141 C 16.021484 16.556641 15.779514 17.598741 15.296875 18.373047 C 14.814236 19.14388 14.113498 19.529297 13.193359 19.529297 C 12.276693 19.529297 11.575955 19.14388 11.089844 18.373047 C 10.607205 17.598741 10.365234 16.556641 10.365234 15.244141 C 10.365234 13.935113 10.607205 12.89388 11.089844 12.123047 C 11.575955 11.348741 12.276693 10.962891 13.193359 10.962891 z M 19.589844 10.962891 C 20.509983 10.962891 21.21072 11.348741 21.693359 12.123047 C 22.175998 12.89388 22.417969 13.935113 22.417969 15.244141 C 22.417969 16.556641 22.175998 17.598741 21.693359 18.373047 C 21.21072 19.14388 20.509983 19.529297 19.589844 19.529297 C 18.673177 19.529297 17.970486 19.14388 17.484375 18.373047 C 17.001736 17.598741 16.761719 16.556641 16.761719 15.244141 C 16.761719 13.935113 17.001736 12.89388 17.484375 12.123047 C 17.970486 11.348741 18.673177 10.962891 19.589844 10.962891 z M 13.193359 11.769531 C 12.613498 11.769531 12.173177 12.092448 11.871094 12.738281 C 11.56901 13.380642 11.417969 14.195964 11.417969 15.185547 C 11.417969 15.411241 11.423611 15.655599 11.4375 15.916016 C 11.451389 16.176432 11.511068 16.528212 11.615234 16.972656 L 14.412109 12.591797 C 14.235026 12.26888 14.042318 12.052517 13.833984 11.941406 C 13.629123 11.826823 13.415582 11.769531 13.193359 11.769531 z M 19.589844 11.769531 C 19.009983 11.769531 18.567708 12.092448 18.265625 12.738281 C 17.963542 13.380642 17.8125 14.195964 17.8125 15.185547 C 17.8125 15.411241 17.820095 15.655599 17.833984 15.916016 C 17.847873 16.176432 17.907552 16.528212 18.011719 16.972656 L 20.808594 12.591797 C 20.63151 12.26888 20.438802 12.052517 20.230469 11.941406 C 20.025608 11.826823 19.812066 11.769531 19.589844 11.769531 z M 14.761719 13.556641 L 11.984375 17.962891 C 12.133681 18.216363 12.305556 18.406684 12.5 18.535156 C 12.694444 18.660156 12.91276 18.722656 13.152344 18.722656 C 13.812066 18.722656 14.280816 18.355252 14.558594 17.619141 C 14.836372 16.879557 14.974609 16.059462 14.974609 15.160156 C 14.974609 14.604601 14.90408 14.07053 14.761719 13.556641 z M 21.15625 13.556641 L 18.380859 17.962891 C 18.530165 18.216363 18.70204 18.406684 18.896484 18.535156 C 19.090929 18.660156 19.307292 18.722656 19.546875 18.722656 C 20.206597 18.722656 20.675347 18.355252 20.953125 17.619141 C 21.230903 16.879557 21.371094 16.059462 21.371094 15.160156 C 21.371094 14.604601 21.298611 14.07053 21.15625 13.556641 z" fill="#289de8" />
|
||||
</graphic></Button>
|
||||
|
|
|
@ -15,7 +15,7 @@ Steps to roll NXDT functionality back:
|
|||
* Set 'Visible' on NXDT Tab selector (SVGPath container)
|
||||
-->
|
||||
|
||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.NSLMainController">
|
||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.NSLMainController">
|
||||
<children>
|
||||
<VBox AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
|
@ -47,14 +47,6 @@ Steps to roll NXDT functionality back:
|
|||
<SVGPath content="M 2.4003906 2 C 1.0683906 2 2.9605947e-16 3.1125 0 4.5 L 0 19.5 A 2.4 2.5 0 0 0 2.4003906 22 L 21.599609 22 A 2.4 2.5 0 0 0 24 19.5 L 24 7 C 24 5.6125 22.919609 4.5 21.599609 4.5 L 12 4.5 L 9.5996094 2 L 2.4003906 2 z M 9 5 L 13 8.5 L 9 12 L 9 10 L 6 10 L 6 7 L 9 7 L 9 5 z M 5 9 L 5 11 L 8 11 L 8 14 L 5 14 L 5 16 L 1 12.5 L 5 9 z M 13.193359 10.962891 C 14.113498 10.962891 14.814236 11.348741 15.296875 12.123047 C 15.779514 12.89388 16.021484 13.935113 16.021484 15.244141 C 16.021484 16.556641 15.779514 17.598741 15.296875 18.373047 C 14.814236 19.14388 14.113498 19.529297 13.193359 19.529297 C 12.276693 19.529297 11.575955 19.14388 11.089844 18.373047 C 10.607205 17.598741 10.365234 16.556641 10.365234 15.244141 C 10.365234 13.935113 10.607205 12.89388 11.089844 12.123047 C 11.575955 11.348741 12.276693 10.962891 13.193359 10.962891 z M 19.589844 10.962891 C 20.509983 10.962891 21.21072 11.348741 21.693359 12.123047 C 22.175998 12.89388 22.417969 13.935113 22.417969 15.244141 C 22.417969 16.556641 22.175998 17.598741 21.693359 18.373047 C 21.21072 19.14388 20.509983 19.529297 19.589844 19.529297 C 18.673177 19.529297 17.970486 19.14388 17.484375 18.373047 C 17.001736 17.598741 16.761719 16.556641 16.761719 15.244141 C 16.761719 13.935113 17.001736 12.89388 17.484375 12.123047 C 17.970486 11.348741 18.673177 10.962891 19.589844 10.962891 z M 13.193359 11.769531 C 12.613498 11.769531 12.173177 12.092448 11.871094 12.738281 C 11.56901 13.380642 11.417969 14.195964 11.417969 15.185547 C 11.417969 15.411241 11.423611 15.655599 11.4375 15.916016 C 11.451389 16.176432 11.511068 16.528212 11.615234 16.972656 L 14.412109 12.591797 C 14.235026 12.26888 14.042318 12.052517 13.833984 11.941406 C 13.629123 11.826823 13.415582 11.769531 13.193359 11.769531 z M 19.589844 11.769531 C 19.009983 11.769531 18.567708 12.092448 18.265625 12.738281 C 17.963542 13.380642 17.8125 14.195964 17.8125 15.185547 C 17.8125 15.411241 17.820095 15.655599 17.833984 15.916016 C 17.847873 16.176432 17.907552 16.528212 18.011719 16.972656 L 20.808594 12.591797 C 20.63151 12.26888 20.438802 12.052517 20.230469 11.941406 C 20.025608 11.826823 19.812066 11.769531 19.589844 11.769531 z M 14.761719 13.556641 L 11.984375 17.962891 C 12.133681 18.216363 12.305556 18.406684 12.5 18.535156 C 12.694444 18.660156 12.91276 18.722656 13.152344 18.722656 C 13.812066 18.722656 14.280816 18.355252 14.558594 17.619141 C 14.836372 16.879557 14.974609 16.059462 14.974609 15.160156 C 14.974609 14.604601 14.90408 14.07053 14.761719 13.556641 z M 21.15625 13.556641 L 18.380859 17.962891 C 18.530165 18.216363 18.70204 18.406684 18.896484 18.535156 C 19.090929 18.660156 19.307292 18.722656 19.546875 18.722656 C 20.206597 18.722656 20.675347 18.355252 20.953125 17.619141 C 21.230903 16.879557 21.371094 16.059462 21.371094 15.160156 C 21.371094 14.604601 21.298611 14.07053 21.15625 13.556641 z" />
|
||||
</graphic>
|
||||
</Tab>
|
||||
<Tab fx:id="PatchesTabHolder" closable="false">
|
||||
<content>
|
||||
<fx:include fx:id="PatchesTab" source="PatchesTab.fxml" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" VBox.vgrow="ALWAYS" />
|
||||
</content>
|
||||
<graphic>
|
||||
<SVGPath content="M 5.7207031,0.20898438 C 4.9048038,0.22904941 4.0506554,0.62991967 3.421875,1.3671875 L 0.88671875,4.3398438 C -0.18640114,5.5981134 -0.18550676,7.3497999 0.890625,8.2675781 L 4.0273438,10.941406 C 6.6544469,8.8548374 9.2821295,6.7689991 11.910156,4.6835938 L 7.3007812,0.75195312 C 6.8972341,0.40778687 6.4010191,0.23063674 5.8828125,0.2109375 5.8288326,0.20888551 5.7750964,0.20764671 5.7207031,0.20898438 Z M 19.292969,0.44921875 C 18.77426,0.4506047 18.272727,0.60956864 17.857422,0.93945312 13.098348,4.719624 9.1497641,7.8546793 4.625,11.451172 H 4.62305 c -1.286759,1.021757 -2.5730291,2.044129 -3.85937502,3.066406 -1.107479,0.879692 -1.16921304,2.628898 -0.140625,3.923828 l 2.42968752,3.060547 c 1.0285869,1.29493 2.7479899,1.629691 3.8554687,0.75 L 24.001876,8.6737831 C 25.109431,7.7941362 25.171165,6.0449297 24.142578,4.75 L 21.712891,1.6914062 C 21.070024,0.8820747 20.157482,0.44690884 19.292969,0.44921875 Z M 14.550781,5.7402344 c 0.139019,-0.00739 0.26467,0.035715 0.341797,0.1328125 l 3.601563,4.5351561 c 0.154252,0.194198 0.05862,0.524614 -0.212891,0.740235 l -7.669922,6.089843 C 10.339882,17.453897 9.9980034,17.47154 9.84375,17.277344 L 6.2421875,12.744141 C 6.0879341,12.549944 6.1836303,12.221473 6.4550781,12.005859 L 14.123047,5.9140625 c 0.135725,-0.1078073 0.288715,-0.166439 0.427734,-0.1738281 z m -1.044922,1.4140625 c -0.161808,0.0078 -0.316999,0.066599 -0.443359,0.1679687 -0.331549,0.2651389 -0.384928,0.7490485 -0.119141,1.0800782 0.265722,0.3309315 0.749564,0.3834278 1.080079,0.1171874 0.329672,-0.2655771 0.3821,-0.7479194 0.117187,-1.078125 C 13.98715,7.2496671 13.751194,7.1429424 13.505859,7.1542969 Z m 2.695313,3.3554691 c -0.161811,0.0078 -0.317006,0.06659 -0.44336,0.167968 -0.331029,0.265668 -0.383535,0.749595 -0.117187,1.080078 0.265523,0.32977 0.74795,0.382208 1.078125,0.117188 0.330388,-0.264941 0.383708,-0.747437 0.119141,-1.078125 -0.153867,-0.192337 -0.390703,-0.299131 -0.636719,-0.287109 z m -3.878906,0.345703 c -0.161811,0.0078 -0.317006,0.06659 -0.44336,0.167969 -0.330387,0.264941 -0.383706,0.747436 -0.11914,1.078124 0.265085,0.331648 0.74908,0.385036 1.080078,0.119141 0.331029,-0.265668 0.383535,-0.749595 0.117187,-1.080078 -0.153858,-0.191033 -0.389764,-0.297009 -0.634765,-0.285156 z m -3.8632816,0.34375 c -0.1624871,0.0074 -0.3184262,0.0662 -0.4453125,0.167969 -0.3310296,0.265668 -0.3835352,0.749595 -0.1171875,1.080078 0.2649414,0.330388 0.747437,0.383707 1.078125,0.11914 C 9.3062569,12.301321 9.3596452,11.817326 9.09375,11.486328 8.9402947,11.294564 8.7043254,11.187834 8.4589844,11.199219 Z M 20.761719,12.232422 12.880859,18.492188 17.5,22.431641 c 1.076128,0.917777 2.805784,0.643037 3.878906,-0.615235 l 2.535156,-2.972656 c 1.073119,-1.258273 1.072172,-3.009959 -0.0039,-3.927734 z m -9.605469,2.33789 c -0.161811,0.0078 -0.317006,0.06659 -0.443359,0.167969 -0.32977,0.265523 -0.382208,0.74795 -0.117188,1.078125 0.264795,0.329134 0.745796,0.382385 1.076172,0.119141 0.331648,-0.265085 0.385036,-0.74908 0.119141,-1.080078 -0.153858,-0.191034 -0.389765,-0.29701 -0.634766,-0.285157 z" />
|
||||
</graphic>
|
||||
</Tab>
|
||||
<Tab closable="false">
|
||||
<content>
|
||||
<fx:include fx:id="SettingsTab" source="SettingsTab.fxml" VBox.vgrow="ALWAYS" />
|
||||
|
|
|
@ -12,12 +12,21 @@
|
|||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.SVGPath?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox spacing="15.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.NxdtController">
|
||||
<VBox spacing="15.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.NxdtController">
|
||||
<HBox alignment="CENTER">
|
||||
<children>
|
||||
<Label styleClass="nxdt" text="nx" />
|
||||
<Label styleClass="bold-text" text="dumptool" />
|
||||
<Label styleClass="nxdt" text="nx">
|
||||
<font>
|
||||
<Font name="System Bold" size="18.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label text="dumptool">
|
||||
<font>
|
||||
<Font name="System Bold" size="18.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</HBox>
|
||||
<GridPane>
|
||||
|
|
|
@ -1,125 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ScrollPane?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.SVGPath?>
|
||||
|
||||
<ScrollPane fitToWidth="true" onDragDropped="#handleDrop" onDragOver="#handleDragOver" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.PatchesController">
|
||||
<VBox fx:id="patchesToolPane" spacing="15.0">
|
||||
<Pane minHeight="-Infinity" prefHeight="10.0" style="-fx-background-color: linear-gradient(from 41px 34px to 50px 50px, reflect, #2cd882 40%, transparent 45%);" />
|
||||
<HBox alignment="CENTER">
|
||||
<children>
|
||||
<Label styleClass="bold-text" text="%tabPatches_Lbl_Title" />
|
||||
</children>
|
||||
</HBox>
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" percentWidth="90.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Separator prefWidth="200.0" styleClass="strangeSeparator" GridPane.columnIndex="1" />
|
||||
</children>
|
||||
</GridPane>
|
||||
<VBox spacing="8.0">
|
||||
<children>
|
||||
<VBox spacing="5.0">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||
<children>
|
||||
<Label minHeight="-Infinity" minWidth="-Infinity" text="%tabPatches_Lbl_Firmware" wrapText="true" />
|
||||
<Label fx:id="shortNameFirmwareLbl" textOverrun="LEADING_WORD_ELLIPSIS" />
|
||||
<Pane HBox.hgrow="ALWAYS" />
|
||||
<Button minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#selectFirmware" styleClass="buttonSelect" text="%tabSplMrg_Btn_SelectFolder" wrapText="true">
|
||||
<graphic>
|
||||
<SVGPath content="M10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6H12L10,4Z" fill="#289de8" />
|
||||
</graphic>
|
||||
</Button>
|
||||
</children>
|
||||
</HBox>
|
||||
<Label fx:id="locationFirmwareLbl" disable="true" styleClass="italic-text" textOverrun="LEADING_WORD_ELLIPSIS" />
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||
<children>
|
||||
<Label minHeight="-Infinity" minWidth="-Infinity" text="%tabPatches_Lbl_Atmo" wrapText="true" />
|
||||
<Label fx:id="shortNameAtmoLbl" textOverrun="LEADING_WORD_ELLIPSIS" />
|
||||
<Pane HBox.hgrow="ALWAYS" />
|
||||
<Button minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#selectAtmosphereFolder" styleClass="buttonSelect" text="%tabSplMrg_Btn_SelectFolder" wrapText="true">
|
||||
<graphic>
|
||||
<SVGPath content="M10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6H12L10,4Z" fill="#289de8" />
|
||||
</graphic>
|
||||
</Button>
|
||||
</children>
|
||||
</HBox>
|
||||
<Label fx:id="locationAtmosphereLbl" disable="true" styleClass="italic-text" textOverrun="LEADING_WORD_ELLIPSIS" />
|
||||
</children>
|
||||
</VBox>
|
||||
<Separator prefWidth="200.0" />
|
||||
<VBox spacing="5.0">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||
<children>
|
||||
<Label minHeight="-Infinity" minWidth="-Infinity" text="%tabPatches_Lbl_Keys" wrapText="true" />
|
||||
<Label fx:id="shortNameKeysLbl" />
|
||||
<Pane HBox.hgrow="ALWAYS" />
|
||||
<Button minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#selectProdKeys" styleClass="buttonSelect" text="%btn_Select">
|
||||
<graphic>
|
||||
<SVGPath content="M22,18V22H18V19H15V16H12L9.74,13.74C9.19,13.91 8.61,14 8,14A6,6 0 0,1 2,8A6,6 0 0,1 8,2A6,6 0 0,1 14,8C14,8.61 13.91,9.19 13.74,9.74L22,18M7,5A2,2 0 0,0 5,7A2,2 0 0,0 7,9A2,2 0 0,0 9,7A2,2 0 0,0 7,5Z" fill="#289de8" />
|
||||
</graphic>
|
||||
</Button>
|
||||
</children>
|
||||
</HBox>
|
||||
<Label fx:id="locationKeysLbl" disable="true" styleClass="italic-text" textOverrun="LEADING_WORD_ELLIPSIS" />
|
||||
</children>
|
||||
</VBox>
|
||||
<VBox spacing="5.0">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||
<children>
|
||||
<Label minHeight="-Infinity" minWidth="-Infinity" text="%tabSplMrg_Lbl_SaveToLocation" wrapText="true" />
|
||||
<Label fx:id="saveToLbl" />
|
||||
<Pane HBox.hgrow="ALWAYS" />
|
||||
<Button minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#selectSaveTo" styleClass="buttonSelect" text="%btn_Select">
|
||||
<graphic>
|
||||
<SVGPath content="M10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6H12L10,4Z" fill="#289de8" />
|
||||
</graphic>
|
||||
</Button>
|
||||
</children>
|
||||
</HBox>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
<VBox.margin>
|
||||
<Insets left="15.0" right="15.0" />
|
||||
</VBox.margin>
|
||||
</VBox>
|
||||
<HBox alignment="CENTER">
|
||||
<children>
|
||||
<Label fx:id="statusLbl" />
|
||||
</children>
|
||||
</HBox>
|
||||
<Pane VBox.vgrow="ALWAYS" />
|
||||
<HBox alignment="CENTER" spacing="5.0">
|
||||
<children>
|
||||
<Button fx:id="makeFsBtn" contentDisplay="TOP" mnemonicParsing="false" styleClass="buttonUp" text="%tabPatches_Btn_MakeFs" />
|
||||
<Button fx:id="makeEsBtn" contentDisplay="TOP" mnemonicParsing="false" styleClass="buttonUp" text="%tabPatches_Btn_MakeEs" />
|
||||
<Button fx:id="makeLoaderBtn" contentDisplay="TOP" mnemonicParsing="false" styleClass="buttonUp" text="%tabPatches_Btn_MakeAtmo" />
|
||||
</children>
|
||||
</HBox>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</VBox>
|
||||
</ScrollPane>
|
|
@ -14,13 +14,18 @@
|
|||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.SVGPath?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<ScrollPane fitToWidth="true" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.RcmController">
|
||||
<ScrollPane fitToWidth="true" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.RcmController">
|
||||
<VBox fx:id="rcmToolPane" spacing="15.0">
|
||||
<Pane minHeight="-Infinity" prefHeight="10.0" style="-fx-background-color: linear-gradient(from 41px 34px to 50px 50px, reflect, #ff1515 40%, transparent 45%);" />
|
||||
<HBox alignment="CENTER">
|
||||
<children>
|
||||
<Label styleClass="bold-text" text="%tabRcm_Lbl_FuseeGelee" />
|
||||
<Label text="%tabRcm_Lbl_FuseeGelee">
|
||||
<font>
|
||||
<Font name="System Bold" size="15.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</HBox>
|
||||
<GridPane>
|
||||
|
@ -52,7 +57,11 @@
|
|||
<Label fx:id="payloadFNameLbl1" />
|
||||
</children>
|
||||
</HBox>
|
||||
<Label fx:id="payloadFPathLbl1" disable="true" styleClass="italic-text" />
|
||||
<Label fx:id="payloadFPathLbl1" disable="true">
|
||||
<font>
|
||||
<Font name="System Italic" size="13.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
<Button fx:id="selPldBtn1" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
|
||||
|
@ -77,7 +86,11 @@
|
|||
<Label fx:id="payloadFNameLbl2" />
|
||||
</children>
|
||||
</HBox>
|
||||
<Label fx:id="payloadFPathLbl2" disable="true" styleClass="italic-text" />
|
||||
<Label fx:id="payloadFPathLbl2" disable="true">
|
||||
<font>
|
||||
<Font name="System Italic" size="13.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
<Button fx:id="selPldBtn2" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
|
||||
|
@ -102,7 +115,11 @@
|
|||
<Label fx:id="payloadFNameLbl3" />
|
||||
</children>
|
||||
</HBox>
|
||||
<Label fx:id="payloadFPathLbl3" disable="true" styleClass="italic-text" />
|
||||
<Label fx:id="payloadFPathLbl3" disable="true">
|
||||
<font>
|
||||
<Font name="System Italic" size="13.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
<Button fx:id="selPldBtn3" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
|
||||
|
@ -127,7 +144,11 @@
|
|||
<Label fx:id="payloadFNameLbl4" />
|
||||
</children>
|
||||
</HBox>
|
||||
<Label fx:id="payloadFPathLbl4" disable="true" styleClass="italic-text" />
|
||||
<Label fx:id="payloadFPathLbl4" disable="true">
|
||||
<font>
|
||||
<Font name="System Italic" size="13.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
<Button fx:id="selPldBtn4" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
|
||||
|
@ -152,7 +173,11 @@
|
|||
<Label fx:id="payloadFNameLbl5" />
|
||||
</children>
|
||||
</HBox>
|
||||
<Label fx:id="payloadFPathLbl5" disable="true" styleClass="italic-text" />
|
||||
<Label fx:id="payloadFPathLbl5" disable="true">
|
||||
<font>
|
||||
<Font name="System Italic" size="13.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</VBox>
|
||||
<Button fx:id="selPldBtn5" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
<VBox spacing="5.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.SettingsBlockGenericController">
|
||||
<VBox spacing="5.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.SettingsBlockGenericController">
|
||||
<children>
|
||||
<Label text="%tab2_Lbl_ApplicationSettings" />
|
||||
<HBox alignment="CENTER_LEFT" spacing="5.0">
|
||||
|
@ -28,11 +28,6 @@
|
|||
<Insets left="5.0" />
|
||||
</VBox.margin>
|
||||
</HBox>
|
||||
<Button fx:id="fontSelectBtn" mnemonicParsing="false" text="%tab2_Btn_ApplicationFont">
|
||||
<VBox.margin>
|
||||
<Insets left="5.0" />
|
||||
</VBox.margin>
|
||||
</Button>
|
||||
<HBox>
|
||||
<children>
|
||||
<VBox>
|
||||
|
|
|
@ -12,14 +12,19 @@
|
|||
<?import javafx.scene.layout.Pane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox fx:id="smToolPane" onDragDropped="#handleDrop" onDragOver="#handleDragOver" spacing="20.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.SplitMergeController">
|
||||
<VBox fx:id="smToolPane" onDragDropped="#handleDrop" onDragOver="#handleDragOver" spacing="20.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.SplitMergeController">
|
||||
<VBox spacing="15.0">
|
||||
<children>
|
||||
<Pane minHeight="-Infinity" prefHeight="10.0" style="-fx-background-color: linear-gradient(from 41px 34px to 50px 50px, reflect, #00c8fc 40%, transparent 45%);" />
|
||||
<HBox alignment="CENTER">
|
||||
<children>
|
||||
<Label styleClass="bold-text" text="%tabSplMrg_Lbl_SplitNMergeTitle" />
|
||||
<Label text="%tabSplMrg_Lbl_SplitNMergeTitle">
|
||||
<font>
|
||||
<Font name="System Bold" size="15.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</HBox>
|
||||
<GridPane>
|
||||
|
|
|
@ -45,7 +45,7 @@ tab2_Cb_AllowXciNszXcz=Allow XCI / NSZ / XCZ files selection for Awoo
|
|||
tab2_Lbl_AllowXciNszXczDesc=Used by applications that support XCI/NSZ/XCZ and utilizes Awoo (aka Adubbz/TinFoil) transfer protocol. Don't change if not sure. Enable for Awoo Installer.
|
||||
tab2_Lbl_Language=Language
|
||||
windowBodyRestartToApplyLang=Please restart application to apply changes.
|
||||
btn_OpenSplitFile=Select split
|
||||
btn_OpenSplitFile=Select split NSP
|
||||
tab2_Lbl_ApplicationSettings=Main settings
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=Split & merge files tool
|
||||
tabSplMrg_RadioBtn_Split=Split
|
||||
|
@ -79,19 +79,3 @@ windowBodyFilesScanned=Files scanned: %d\nWould be added: %d
|
|||
tab2_Lbl_AwooBlockTitle=Awoo Installer and compatible
|
||||
tabRcm_Lbl_Payload=Payload:
|
||||
tabRcm_Lbl_FuseeGelee=Fus\u00E9e Gel\u00E9e RCM
|
||||
tabPatches_Lbl_Firmware=Firmware:
|
||||
tabPatches_Lbl_Atmo=Atmosphere:
|
||||
tabPatches_Btn_fromFolder=From folder
|
||||
tabPatches_Btn_asZipFile=as ZIP file
|
||||
tabPatches_Lbl_Title=Patches
|
||||
tabPatches_Lbl_Keys=Keys:
|
||||
tabPatches_Btn_MakeEs=Make ES
|
||||
tabPatches_Btn_MakeFs=Make FS
|
||||
tabPatches_Btn_MakeAtmo=Make Loader (Atmosphere)
|
||||
tabPatches_Btn_MakeAll=Make all
|
||||
tabPatches_ServiceWindowMessageEsFs=Both firmware and keys should be set to generate patches. Otherwise, it's not clear what to patch.
|
||||
tabPatches_ServiceWindowMessageLoader=Atmosphere folder should be defined to generate 'Loader' patch.
|
||||
tab2_Btn_ApplicationFont=Change application font
|
||||
btn_ResetToDefaults=Reset
|
||||
fontPreviewText=Text preview
|
||||
fontSize=Font size:
|
||||
|
|
|
@ -43,7 +43,7 @@ tab2_Cb_AllowXciNszXcz=\u0627\u0644\u0633\u0645\u0627\u062D \u0644\u0628\u0631\u
|
|||
tab2_Lbl_AllowXciNszXczDesc=\u0645\u0633\u062A\u062E\u062F\u0645 \u0628\u0627\u0644\u0628\u0631\u0627\u0645\u062C \u0627\u0644\u062A\u064A \u062A\u062F\u0639\u0645 \u0627\u0644\u0645\u0644\u0641\u0627\u062A \u0645\u0646 \u0627\u0644\u0646\u0648\u0639 "\u0625\u0643\u0633 \u0633\u064A \u0622\u064A" \u0623\u0648 "\u0625\u0646 \u0625\u0633 \u0632\u062F" \u0623\u0648 "\u0625\u0643\u0633 \u0633\u064A \u0632\u062F" \u0648\u062A\u0633\u062A\u062E\u062F\u0645 \u0628\u0631\u0648\u062A\u0648\u0643\u0648\u0644 \u0627\u0644\u0646\u0642\u0644 \u0644\u0628\u0631\u0646\u0627\u0645\u062C \u0627\u0644 "\u062A\u064A\u0646\u0641\u0648\u064A\u0644". \u0644\u0627 \u062A\u0639\u062F\u0644 \u0625\u0630\u0627 \u0644\u0645 \u062A\u0643\u0646 \u0645\u062A\u0623\u0643\u062F . \u0648\u0641\u0639\u0644\u0647 \u0625\u0630\u0627 \u0643\u0646\u062A \u062A\u0633\u062A\u062E\u062F\u0645 \u0628\u0631\u0646\u0627\u0645\u062C \u062A\u0646\u0635\u064A\u0628 "\u0623\u0648\u0648\u0648".
|
||||
tab2_Lbl_Language=\u0627\u0644\u0644\u063A\u0629
|
||||
windowBodyRestartToApplyLang=\u0645\u0646 \u0641\u0636\u0644\u0643 \u0623\u0639\u062F \u062A\u0634\u0641\u064A\u0644 \u0627\u0644\u0628\u0631\u0646\u0627\u0645\u062C \u0644\u062A\u0637\u0628\u064A\u0642 \u0627\u0644\u062A\u0639\u062F\u064A\u0644\u0627\u062A.
|
||||
btn_OpenSplitFile=\u0627\u062E\u062A\u0631 \u062A\u0642\u0633\u064A\u0645 \u0645\u0644\u0641 \u0627\u0644
|
||||
btn_OpenSplitFile=\u0627\u062E\u062A\u0631 \u062A\u0642\u0633\u064A\u0645 \u0645\u0644\u0641 \u0627\u0644 "\u0625\u0646 \u0625\u0633 \u0628\u064A"
|
||||
tab2_Lbl_ApplicationSettings=\u0627\u0644\u0625\u0639\u062F\u0627\u062F\u0627\u062A \u0627\u0644\u0631\u0626\u064A\u0633\u064A\u0629
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=\u0623\u062F\u0627\u0629 \u062A\u0642\u0633\u064A\u0645 \u0648\u062F\u0645\u062C \u0627\u0644\u0645\u0644\u0641\u0627\u062A
|
||||
tabSplMrg_RadioBtn_Split=\u062A\u0642\u0633\u064A\u0645
|
||||
|
|
|
@ -43,7 +43,7 @@ tab2_Cb_AllowXciNszXcz=Umo\u017Enit volbu XCI / NSZ / XCZ soubor\u016F pro Awoo
|
|||
tab2_Lbl_AllowXciNszXczDesc=Lze vyu\u017E\u00EDt v aplikac\u00EDch, kter\u00E9 podporuj\u00ED soubory typu XCI/NSZ/XCZ a pro p\u0159enos vyu\u017E\u00EDvaj\u00ED protokol Tinfoil. Nem\u011B\u0148te, jestli tomu nerozum\u00EDte. Aktivujte pro Awoo Installer.
|
||||
tab2_Lbl_Language=Jazyk
|
||||
windowBodyRestartToApplyLang=Pro aplikov\u00E1n\u00ED zm\u011Bn restartujte aplikaci.
|
||||
btn_OpenSplitFile=Zvolit rozd\u011Blen\u00E9 soubor
|
||||
btn_OpenSplitFile=Zvolit rozd\u011Blen\u00E9 NSP
|
||||
tab2_Lbl_ApplicationSettings=Hlavn\u00ED nastaven\u00ED
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=Utilita k rozd\u011Blen\u00ED/slou\u010Den\u00ED soubor\u016F
|
||||
tabSplMrg_RadioBtn_Split=Rozd\u011Blit
|
||||
|
|
|
@ -45,7 +45,7 @@ tab2_Cb_AllowXciNszXcz=Erlaube XCI- NSZ- XCZ-Dateien-Verwendung f\u00FCr Awoo
|
|||
tab2_Lbl_AllowXciNszXczDesc=Von einigen Drittanbietern verwendet, welche XCI/NSZ/XCZ unterst\u00FCtzen, nutzt z Transfer Protocol. Nicht \u00E4ndern, wenn unsicher.
|
||||
tab2_Lbl_Language=Sprache
|
||||
windowBodyRestartToApplyLang=Bitte die Applikation neustarten um die Einstellungen zu \u00FCbernehmen.
|
||||
btn_OpenSplitFile=Split-file ausw\uFFFDhlen
|
||||
btn_OpenSplitFile=Split-NSP ausw\uFFFDhlen
|
||||
tab2_Cb_GLshowNspOnly=Nur *.nsp in GoldLeaf zeigen.
|
||||
btn_Cancel=Abbrechen
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
btn_OpenFile=Select files
|
||||
btn_OpenFolders=Select folder
|
||||
btn_Upload=Upload to NS
|
||||
btn_OpenFolders_tooltip=Select a folder to be scanned.\nThis folder and all of its subfolders will be scanned.\nAll matching files will be added to the list.
|
||||
tab3_Txt_EnteredAsMsg1=You have been entered as:
|
||||
tab3_Txt_EnteredAsMsg2=You should be root or have configured 'udev' rules for this user to avoid any issues.
|
||||
tab3_Txt_FilesToUploadTitle=Files to upload:
|
||||
tab3_Txt_GreetingsMessage=Welcome to NS-USBloader
|
||||
tab3_Txt_NoFolderOrFileSelected=No files selected: nothing to upload.
|
||||
windowBodyConfirmExit=Data transfer is in progress and closing this application will interrupt it.\nIt's the worse thing you can do now.\nInterrupt proccess and exit?
|
||||
windowTitleConfirmExit=No, don't do this!
|
||||
btn_Stop=Interrupt
|
||||
tab3_Txt_GreetingsMessage2=--\n\
|
||||
Source: https://git.redrise.ru/desu/ns-usbloader\n\
|
||||
Mirror: https://github.com/developersu/ns-usbloader/\n\
|
||||
Site: https://redrise.ru\n\
|
||||
Dmitry Isaenko [developer.su]
|
||||
tab1_table_Lbl_Status=Status
|
||||
tab1_table_Lbl_FileName=File name
|
||||
tab1_table_Lbl_Size=Size
|
||||
tab1_table_Lbl_Upload=Upload?
|
||||
tab1_table_contextMenu_Btn_BtnDelete=Remove
|
||||
tab1_table_contextMenu_Btn_DeleteAll=Remove all
|
||||
tab2_Lbl_HostIP=Host IP
|
||||
tab1_Lbl_NSIP=NS IP:
|
||||
tab2_Cb_ValidateNSHostName=Always validate NS IP input.
|
||||
windowBodyBadIp=Are you sure that you entered NS IP address correctly?
|
||||
windowTitleBadIp=IP address of NS most likely incorrect
|
||||
tab2_Cb_ExpertMode=Expert mode (NET setup)
|
||||
tab2_Lbl_HostPort=port
|
||||
tab2_Cb_AutoDetectIp=Auto-detect IP
|
||||
tab2_Cb_RandSelectPort=Randomly get port
|
||||
tab2_Cb_DontServeRequests=Don't serve requests
|
||||
tab2_Lbl_DontServeRequestsDesc=If selected, this computer won't reply to NSP files requests coming from NS (over the net) and use defined host settings to tell Awoo where should it look for files.
|
||||
tab2_Lbl_HostExtra=extra
|
||||
windowTitleErrorPort=Port set incorrectly!
|
||||
windowBodyErrorPort=Port can't be 0 or greater than 65535.
|
||||
tab2_Cb_AutoCheckForUpdates=Auto check for updates
|
||||
windowTitleNewVersionAval=New version available
|
||||
windowTitleNewVersionNOTAval=No new versions available
|
||||
windowTitleNewVersionUnknown=Unable to check for new versions
|
||||
windowBodyNewVersionUnknown=Something went wrong\nMaybe internet unavailable, or GitHub is down
|
||||
windowBodyNewVersionNOTAval=You're using the latest version
|
||||
tab2_Cb_AllowXciNszXcz=Allow XCI / NSZ / XCZ files selection for Awoo
|
||||
tab2_Lbl_AllowXciNszXczDesc=Used by applications that support XCI/NSZ/XCZ and utilizes Awoo (aka Adubbz/TinFoil) transfer protocol. Don't change if not sure. Enable for Awoo Installer.
|
||||
tab2_Lbl_Language=Language
|
||||
windowBodyRestartToApplyLang=Please restart application to apply changes.
|
||||
btn_OpenSplitFile=Select split NSP
|
||||
tab2_Lbl_ApplicationSettings=Main settings
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=Split & merge files tool
|
||||
tabSplMrg_RadioBtn_Split=Split
|
||||
tabSplMrg_RadioBtn_Merge=Merge
|
||||
tabSplMrg_Txt_File=File:
|
||||
tabSplMrg_Txt_Folder=Split file (folder):
|
||||
tabSplMrg_Btn_SelectFile=Select File
|
||||
tabSplMrg_Btn_SelectFolder=Select Folder
|
||||
tabSplMrg_Lbl_SaveToLocation=Save to:
|
||||
tabSplMrg_Btn_ChangeSaveToLocation=Change
|
||||
tabSplMrg_Btn_Convert=Convert
|
||||
windowTitleError=Error
|
||||
windowBodyPleaseFinishTransfersFirst=Unable to split/merge files when application USB/Network process active. Please interrupt active transfers first.
|
||||
done_txt=Done!
|
||||
failure_txt=Failed
|
||||
btn_Select=Select
|
||||
btn_InjectPayloader=Inject payload
|
||||
tabNXDT_Btn_Start=Start!
|
||||
tab2_Btn_InstallDrivers=Download and install drivers
|
||||
windowTitleDownloadDrivers=Download and install drivers
|
||||
windowBodyDownloadDrivers=Downloading drivers (libusbK v3.0.7.0)...
|
||||
btn_Cancel=Cancel
|
||||
btn_Close=Close
|
||||
tab2_Cb_GlVersion=GoldLeaf version
|
||||
tab2_Cb_GLshowNspOnly=Show only *.nsp in GoldLeaf.
|
||||
windowBodyPleaseStopOtherProcessFirst=Please stop other active process before continuing.
|
||||
tab2_Cb_foldersSelectorForRoms=Select folder with ROM files instead of selecting ROMs individually.
|
||||
tab2_Cb_foldersSelectorForRomsDesc=Changes 'Select files' button behaviour on 'Games' tab: instead of selecting ROM files one-by-one you can choose folder to add every supported file at once.
|
||||
windowTitleAddingFiles=Searching for files...
|
||||
windowBodyFilesScanned=Files scanned: %d\nWould be added: %d
|
||||
tabRcm_Lbl_FuseeGelee=Fus\u00E9e Gel\u00E9e RCM
|
||||
tabRcm_Lbl_Payload=Payload:
|
|
@ -1,8 +1,6 @@
|
|||
btn_OpenFile=S\u00E9l\u00E9ctionner les fichiers
|
||||
btn_OpenFolders=S\u00E9l\u00E9ctionner un dossier
|
||||
btn_OpenFile=Selectionner les fichiers
|
||||
btn_Upload=Envoyer vers NS
|
||||
btn_OpenFolders_tooltip=S\u00E9lectionnez un dossier \u00E0 analyser.\nCe dossier et tous ses sous-dossiers seront analys\u00E9s.\nTous les fichiers pertinents seront ajout\u00E9s à la liste.
|
||||
tab3_Txt_EnteredAsMsg1=Vous \u00EAtes connect\u00E9 en tant que :
|
||||
tab3_Txt_EnteredAsMsg1=Vous etes connect\u00E9 en tant que:
|
||||
tab3_Txt_EnteredAsMsg2=Vous devez \u00EAtre root ou avoir configur\u00E9 les r\u00E8gles 'udev' pour cet utilisateur afin d'\u00E9viter tout probl\u00E8me.
|
||||
tab3_Txt_FilesToUploadTitle=Fichiers a envoyer:
|
||||
tab3_Txt_GreetingsMessage=Bienvenue sur NS-USBloader
|
||||
|
@ -15,17 +13,17 @@ Source : https://git.redrise.ru/desu/ns-usbloader\n\
|
|||
Mirror: https://github.com/developersu/ns-usbloader/\n\
|
||||
Site: https://redrise.ru\n\
|
||||
Dmitry Isaenko [developer.su]
|
||||
tab1_table_Lbl_Status=Statut
|
||||
tab1_table_Lbl_FileName=Nom de fichier
|
||||
tab1_table_Lbl_Size=Taille
|
||||
tab1_table_Lbl_Upload=Envoyer ?
|
||||
tab1_table_Lbl_Size=Taille
|
||||
tab1_table_Lbl_FileName=Nom de fichier
|
||||
tab1_table_Lbl_Status=Statut
|
||||
tab1_table_contextMenu_Btn_BtnDelete=Supprimer
|
||||
tab1_table_contextMenu_Btn_DeleteAll=Supprimer tout
|
||||
tab2_Lbl_HostIP=IP de l'ordinateur
|
||||
tab1_Lbl_NSIP=IP de NS:
|
||||
tab2_Cb_ValidateNSHostName=Toujours v\u00E9rifier que l'adresse IP de NS entr\u00E9e est correcte
|
||||
windowBodyBadIp=\u00CAtes-vous s\u00FBr que l'adresse IP de NS entr\u00E9e est correcte ?
|
||||
windowTitleBadIp=L'adresse IP de NS est probablement incorrecte
|
||||
windowBodyBadIp=\u00CAtes-vous s\u00FBr que l'adresse IP de NS entr\u00E9e est correcte ?
|
||||
tab2_Cb_ExpertMode=Mode expert
|
||||
tab2_Lbl_HostPort=port
|
||||
tab2_Cb_AutoDetectIp=D\u00E9tection automatique d'IP
|
||||
|
@ -39,24 +37,12 @@ tab2_Cb_AutoCheckForUpdates=V\u00E9rifier automatiquement les mises \u00E0 jour
|
|||
windowTitleNewVersionAval=Nouvelle version disponible
|
||||
windowTitleNewVersionNOTAval=Aucune nouvelle version disponible
|
||||
windowTitleNewVersionUnknown=Impossible de v\u00E9rifier les nouvelles versions
|
||||
windowBodyNewVersionUnknown=Une erreur s'est produite\nPeut-\u00EAtre des probl\u00E8mes de connexion Internet ou GitHub est en panne
|
||||
windowBodyNewVersionNOTAval=Vous utilisez la derni\u00E8re version
|
||||
windowBodyNewVersionUnknown=Une erreur s'est produite\nPeut-\u00EAtre des probl\u00E8mes de connexion Internet ou GitHub est en panne
|
||||
tab2_Cb_AllowXciNszXcz=Autoriser la s\u00E9lection de fichiers XCI / NSZ / XCZ pour Awoo
|
||||
tab2_Lbl_AllowXciNszXczDesc=Utilis\u00E9 par certaines applications tierces prenant en charge XCI/NSZ/XCZ et utilisant le protocole de transfert TinFoil. Ne changez pas en cas de doute.
|
||||
tab2_Lbl_Language=Langue
|
||||
windowBodyRestartToApplyLang=Red\u00E9marrez l'application pour appliquer les modifications.
|
||||
btn_OpenSplitFile=S\u00E9lectionner un NSP divis\u00E9
|
||||
tab2_Lbl_ApplicationSettings=Param\u00E8tres principaux
|
||||
tabSplMrg_RadioBtn_Split=Diviser
|
||||
tabSplMrg_RadioBtn_Merge=Fusionner
|
||||
failure_txt=Erreur
|
||||
btn_Select=S\u00E9lectionner
|
||||
btn_InjectPayloader=Injecter le payload
|
||||
tab2_Btn_InstallDrivers=T\u00E9l\u00E9charger et installer les pilotes
|
||||
windowTitleDownloadDrivers=T\u00E9l\u00E9charger et installer les pilotes
|
||||
tab2_Lbl_Language=La langue
|
||||
btn_Cancel=Annuler
|
||||
btn_Close=Fermer
|
||||
tab2_Cb_GlVersion=Version de GoldLeaf
|
||||
tab2_Cb_GLshowNspOnly=N'afficher que les *.nsp dans GoldLeaf.
|
||||
tab2_Cb_foldersSelectorForRoms=S\u00E9lectionnez un dossier contenant des fichiers ROM plutôt que de les s\u00E9lectionner individuellement.
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ tab2_Cb_AllowXciNszXcz=Consenti la selezione di file XCI / NSZ / XCZ per Awoo
|
|||
tab2_Lbl_AllowXciNszXczDesc=Usato dalle applicazioni che supportano XCI/NSZ/XCZ ed utilizza il protocollo di trasferimento di Awoo (o Adubbz/TinFoil). Non cambiarlo se non sei sicuro. Attivalo per Awoo Installer.
|
||||
tab2_Lbl_Language=Lingua
|
||||
windowBodyRestartToApplyLang=Riavvia l'applicazione per applicare le modifiche.
|
||||
btn_OpenSplitFile=Seleziona il file truncato
|
||||
btn_OpenSplitFile=Seleziona NSP troncato
|
||||
tab2_Lbl_ApplicationSettings=Impostazioni principali
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=Strumento tronca e unisci file
|
||||
tabSplMrg_RadioBtn_Split=Tronca
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
btn_OpenFile=\u30D5\u30A1\u30A4\u30EB\u3092\u9078\u629E
|
||||
btn_OpenFolders=\u30D5\u30A9\u30EB\u30C0\u30FC\u3092\u9078\u629E
|
||||
btn_Upload=NS\u306B\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9
|
||||
btn_OpenFolders_tooltip=\u30B9\u30AD\u30E3\u30F3\u3059\u308B\u30D5\u30A9\u30EB\u30C0\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n\u3053\u306E\u30D5\u30A9\u30EB\u30C0\u3068\u305D\u306E\u3059\u3079\u3066\u306E\u30B5\u30D6\u30D5\u30A9\u30EB\u30C0\u304C\u30B9\u30AD\u30E3\u30F3\u3055\u308C\u307E\u3059\u3002\n\u4E00\u81F4\u3059\u308B\u3059\u3079\u3066\u306E\u30D5\u30A1\u30A4\u30EB\u304C\u30EA\u30B9\u30C8\u306B\u8FFD\u52A0\u3055\u308C\u307E\u3059\u3002
|
||||
tab3_Txt_EnteredAsMsg1=\u3042\u306A\u305F\u306F\u6B21\u306E\u3088\u3046\u306B\u5165\u529B\u3055\u308C\u307E\u3057\u305F:
|
||||
tab3_Txt_EnteredAsMsg2=\u554F\u984C\u3092\u56DE\u907F\u3059\u308B\u306B\u306F\u3001root \u306B\u306A\u308B\u304B\u3001\u3053\u306E\u30E6\u30FC\u30B6\u30FC\u306B\u300Cudev\u300D\u30EB\u30FC\u30EB\u3092\u8A2D\u5B9A\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
|
||||
tab3_Txt_FilesToUploadTitle=\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3059\u308B\u30D5\u30A1\u30A4\u30EB:
|
||||
tab3_Txt_GreetingsMessage=NS-USBloader\u3078\u3088\u3046\u3053\u305D
|
||||
tab3_Txt_NoFolderOrFileSelected=\u30D5\u30A1\u30A4\u30EB\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093: \u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3059\u308B\u3082\u306E\u304C\u3042\u308A\u307E\u305B\u3093\u3002
|
||||
windowBodyConfirmExit=\u30C7\u30FC\u30BF\u8EE2\u9001\u304C\u9032\u884C\u4E2D\u3067\u3059\u3002\u3053\u306E\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u3092\u9589\u3058\u308B\u3068\u4E2D\u65AD\u3055\u308C\u307E\u3059\u3002\n\u6700\u60AA\u306E\u4E8B\u614B\u3067\u3059\u3002\n\u51E6\u7406\u3092\u4E2D\u65AD\u3057\u3066\u7D42\u4E86\u3057\u307E\u3059\u304B?
|
||||
windowTitleConfirmExit=\u3044\u3044\u3048\u3001\u3053\u308C\u3092\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\uFF01
|
||||
btn_Stop=\u5272\u308A\u8FBC\u307F
|
||||
tab3_Txt_GreetingsMessage2=--\n\
|
||||
Source: https://git.redrise.ru/desu/ns-usbloader\n\
|
||||
Mirror: https://github.com/developersu/ns-usbloader/\n\
|
||||
Site: https://redrise.ru\n\
|
||||
Dmitry Isaenko [developer.su]
|
||||
tab1_table_Lbl_Status=\u30B9\u30C6\u30FC\u30BF\u30B9
|
||||
tab1_table_Lbl_FileName=\u30D5\u30A1\u30A4\u30EB\u540D
|
||||
tab1_table_Lbl_Size=\u30B5\u30A4\u30BA
|
||||
tab1_table_Lbl_Upload=\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\uFF1F
|
||||
tab1_table_contextMenu_Btn_BtnDelete=\u524A\u9664\u3059\u308B
|
||||
tab1_table_contextMenu_Btn_DeleteAll=\u3059\u3079\u3066\u524A\u9664\u3059\u308B
|
||||
tab2_Lbl_HostIP=\u30DB\u30B9\u30C8 IP
|
||||
tab1_Lbl_NSIP=NS IP:
|
||||
tab2_Cb_ValidateNSHostName=NS IP \u5165\u529B\u3092\u5E38\u306B\u691C\u8A3C\u3057\u307E\u3059\u3002
|
||||
windowBodyBadIp=NS IP \u30A2\u30C9\u30EC\u30B9\u3092\u6B63\u3057\u304F\u5165\u529B\u3057\u307E\u3057\u305F\u304B?
|
||||
windowTitleBadIp=NS\u306EIP\u30A2\u30C9\u30EC\u30B9\u304C\u9593\u9055\u3063\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059
|
||||
tab2_Cb_ExpertMode=\u30A8\u30AD\u30B9\u30D1\u30FC\u30C8\u30E2\u30FC\u30C9 (NET \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7)
|
||||
tab2_Lbl_HostPort=\u30DD\u30FC\u30C8
|
||||
tab2_Cb_AutoDetectIp=IP\u306E\u81EA\u52D5\u691C\u51FA
|
||||
tab2_Cb_RandSelectPort=\u30E9\u30F3\u30C0\u30E0\u306B\u30DD\u30FC\u30C8\u3092\u53D6\u5F97
|
||||
tab2_Cb_DontServeRequests=\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u51E6\u7406\u3057\u306A\u3044
|
||||
tab2_Lbl_DontServeRequestsDesc=\u9078\u629E\u3059\u308B\u3068\u3001\u3053\u306E\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u306F NS (\u30CD\u30C3\u30C8\u7D4C\u7531) \u304B\u3089\u306E NSP \u30D5\u30A1\u30A4\u30EB\u8981\u6C42\u306B\u5FDC\u7B54\u305B\u305A\u3001\u5B9A\u7FA9\u3055\u308C\u305F\u30DB\u30B9\u30C8\u8A2D\u5B9A\u3092\u4F7F\u7528\u3057\u3066 Awoo \u30A4\u30F3\u30B9\u30C8\u30FC\u30E9 (\u307E\u305F\u306F\u4E92\u63DB\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3) \u306B\u30D5\u30A1\u30A4\u30EB\u3092\u63A2\u3059\u5834\u6240\u3092\u4F1D\u3048\u307E\u3059\u3002
|
||||
tab2_Lbl_HostExtra=\u30A8\u30AD\u30B9\u30C8\u30E9
|
||||
windowTitleErrorPort=\u30DD\u30FC\u30C8\u304C\u6B63\u3057\u304F\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093!
|
||||
windowBodyErrorPort=\u30DD\u30FC\u30C8\u3092 0 \u307E\u305F\u306F 65535 \u3088\u308A\u5927\u304D\u304F\u3059\u308B\u3053\u3068\u306F\u3067\u304D\u307E\u305B\u3093\u3002
|
||||
tab2_Cb_AutoCheckForUpdates=\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u306E\u81EA\u52D5\u30C1\u30A7\u30C3\u30AF
|
||||
windowTitleNewVersionAval=\u65B0\u3057\u3044\u30D0\u30FC\u30B8\u30E7\u30F3\u304C\u5229\u7528\u53EF\u80FD\u3067\u3059
|
||||
windowTitleNewVersionNOTAval=\u65B0\u3057\u3044\u30D0\u30FC\u30B8\u30E7\u30F3\u306F\u3042\u308A\u307E\u305B\u3093
|
||||
windowTitleNewVersionUnknown=\u65B0\u3057\u3044\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093
|
||||
windowBodyNewVersionUnknown=\u554F\u984C\u304C\u767A\u751F\u3057\u307E\u3057\u305F\n\u30A4\u30F3\u30BF\u30FC\u30CD\u30C3\u30C8\u304C\u5229\u7528\u3067\u304D\u306A\u3044\u304B\u3001GitHub\u304C\u30C0\u30A6\u30F3\u3057\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059
|
||||
windowBodyNewVersionNOTAval=\u6700\u65B0\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u3066\u3044\u307E\u3059
|
||||
tab2_Cb_AllowXciNszXcz=Awoo \u306E XCI / NSZ / XCZ \u30D5\u30A1\u30A4\u30EB\u306E\u9078\u629E\u3092\u8A31\u53EF
|
||||
tab2_Lbl_AllowXciNszXczDesc=XCI/NSZ/XCZ \u3092\u30B5\u30DD\u30FC\u30C8\u3057\u3001Awoo (\u5225\u540D Adubbz/TinFoil) \u8EE2\u9001\u30D7\u30ED\u30C8\u30B3\u30EB\u3092\u5229\u7528\u3059\u308B\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u3067\u4F7F\u7528\u3055\u308C\u307E\u3059\u3002 \u3088\u304F\u308F\u304B\u3089\u306A\u3044\u5834\u5408\u306F\u5909\u66F4\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002 Awoo \u30A4\u30F3\u30B9\u30C8\u30FC\u30E9\u30FC\u3092\u6709\u52B9\u306B\u3057\u307E\u3059\u3002
|
||||
tab2_Lbl_Language=\u8A00\u8A9E
|
||||
windowBodyRestartToApplyLang=\u5909\u66F4\u3092\u9069\u7528\u3059\u308B\u306B\u306F\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u3092\u518D\u8D77\u52D5\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
||||
btn_OpenSplitFile=\u30B9\u30D7\u30EA\u30C3\u30C8ROM\u3092\u9078\u629E
|
||||
tab2_Lbl_ApplicationSettings=\u4E3B\u306A\u8A2D\u5B9A
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=\u30D5\u30A1\u30A4\u30EB\u306E\u5206\u5272\u3068\u7D50\u5408\u30C4\u30FC\u30EB
|
||||
tabSplMrg_RadioBtn_Split=\u30D5\u30A1\u30A4\u30EB\u306E\u5206\u5272\u3068\u7D50\u5408\u30C4\u30FC\u30EB
|
||||
tabSplMrg_RadioBtn_Merge=\u30DE\u30FC\u30B8
|
||||
tabSplMrg_Txt_File=\u30D5\u30A1\u30A4\u30EB\uFF1A
|
||||
tabSplMrg_Txt_Folder=\u5206\u5272\u30D5\u30A1\u30A4\u30EB (\u30D5\u30A9\u30EB\u30C0\u30FC):
|
||||
tabSplMrg_Btn_SelectFile=\u30D5\u30A1\u30A4\u30EB\u3092\u9078\u3076
|
||||
tabSplMrg_Btn_SelectFolder=\u30D5\u30A9\u30EB\u30C0\u30FC\u3092\u9078\u629E
|
||||
tabSplMrg_Lbl_SaveToLocation=\u306B\u4FDD\u5B58\uFF1A
|
||||
tabSplMrg_Btn_ChangeSaveToLocation=\u5909\u5316\u3059\u308B
|
||||
tabSplMrg_Btn_Convert=\u5909\u63DB
|
||||
windowTitleError=\u30A8\u30E9\u30FC
|
||||
windowBodyPleaseFinishTransfersFirst=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3 USB/\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF \u30D7\u30ED\u30BB\u30B9\u304C\u30A2\u30AF\u30C6\u30A3\u30D6\u306A\u5834\u5408\u3001\u30D5\u30A1\u30A4\u30EB\u3092\u5206\u5272/\u30DE\u30FC\u30B8\u3067\u304D\u307E\u305B\u3093\u3002 \u6700\u521D\u306B\u30A2\u30AF\u30C6\u30A3\u30D6\u306A\u8EE2\u9001\u3092\u4E2D\u65AD\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
||||
done_txt=\u7D42\u308F\u308A\uFF01
|
||||
failure_txt=\u5931\u6557
|
||||
btn_Select=\u9078\u629E\u3059\u308B
|
||||
btn_InjectPayloader=\u30DA\u30A4\u30ED\u30FC\u30C9\u3092\u633F\u5165\u3059\u308B
|
||||
tabNXDT_Btn_Start=\u59CB\u3081\u308B\uFF01
|
||||
tab2_Btn_InstallDrivers=\u30C9\u30E9\u30A4\u30D0\u30FC\u306E\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3068\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB
|
||||
windowTitleDownloadDrivers=\u30C9\u30E9\u30A4\u30D0\u30FC\u306E\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3068\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB
|
||||
windowBodyDownloadDrivers=\u30C9\u30E9\u30A4\u30D0\u30FC\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3057\u3066\u3044\u307E\u3059 (libusbK v3.0.7.0)...
|
||||
btn_Cancel=\u30AD\u30E3\u30F3\u30BB\u30EB
|
||||
btn_Close=\u9589\u3058\u308B
|
||||
tab2_Cb_GlVersion=GoldLeaf\u30D0\u30FC\u30B8\u30E7\u30F3
|
||||
tab2_Cb_GLshowNspOnly=GoldLeaf\u3067 *.nsp \u306E\u307F\u3092\u8868\u793A\u3057\u307E\u3059\u3002
|
||||
windowBodyPleaseStopOtherProcessFirst=\u7D9A\u884C\u3059\u308B\u524D\u306B\u3001\u4ED6\u306E\u30A2\u30AF\u30C6\u30A3\u30D6\u306A\u30D7\u30ED\u30BB\u30B9\u3092\u505C\u6B62\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
||||
tab2_Cb_foldersSelectorForRoms=ROM \u3092\u500B\u5225\u306B\u9078\u629E\u3059\u308B\u306E\u3067\u306F\u306A\u304F\u3001ROM \u30D5\u30A1\u30A4\u30EB\u306E\u3042\u308B\u30D5\u30A9\u30EB\u30C0\u3092\u9078\u629E\u3057\u307E\u3059\u3002
|
||||
tab2_Cb_foldersSelectorForRomsDesc=[\u30B2\u30FC\u30E0] \u30BF\u30D6\u306E [\u30D5\u30A1\u30A4\u30EB\u3092\u9078\u629E] \u30DC\u30BF\u30F3\u306E\u52D5\u4F5C\u3092\u5909\u66F4: ROM \u30D5\u30A1\u30A4\u30EB\u3092 1 \u3064\u305A\u3064\u9078\u629E\u3059\u308B\u4EE3\u308F\u308A\u306B\u3001\u30D5\u30A9\u30EB\u30C0\u30FC\u3092\u9078\u629E\u3057\u3066\u3001\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u308B\u3059\u3079\u3066\u306E\u30D5\u30A1\u30A4\u30EB\u3092\u4E00\u5EA6\u306B\u8FFD\u52A0\u3067\u304D\u307E\u3059\u3002
|
||||
windowTitleAddingFiles=\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u7D22\u3057\u3066\u3044\u307E\u3059...
|
||||
windowBodyFilesScanned=\u30B9\u30AD\u30E3\u30F3\u3055\u308C\u305F\u30D5\u30A1\u30A4\u30EB: %d\n\u8FFD\u52A0\u4E88\u5B9A: %d
|
||||
tab2_Lbl_AwooBlockTitle=Awoo\u30A4\u30F3\u30B9\u30C8\u30FC\u30E9\u30FC\u3068\u4E92\u63DB\u6027
|
||||
tabRcm_Lbl_Payload=\u30DA\u30A4\u30ED\u30FC\u30C9\uFF1A
|
||||
tabRcm_Lbl_FuseeGelee=Fus\u00E9e Gel\u00E9e RCM
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
btn_OpenFile=\u30D5\u30A1\u30A4\u30EB\u9078\u629E
|
||||
btn_OpenFolders=\u30D5\u30A9\u30EB\u30C0\u30FC\u9078\u629E
|
||||
btn_Upload=NS\u3093\u304B\u3044\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9
|
||||
btn_OpenFolders_tooltip=\u30B9\u30AD\u30E3\u30F3\u3059\u308B\u30D5\u30A9\u30EB\u30C0\u9078\u629E\u3057\u304F\u3043\u307F\u305D\u30FC\u308C\u30FC\u3002\n\u304F\u306C\u30D5\u30A9\u30EB\u30C0\u3068\u3045\u3046\u306C\u307E\u3058\u308A\u306C\u30B5\u30D6\u30D5\u30A9\u30EB\u30C0\u306C\u30B9\u30AD\u30E3\u30F3\u3055\u308A\u3084\u3073\u30FC\u3093\u3002\n\u4E00\u81F4\u3059\u308B\u307E\u3058\u308A\u306C\u30D5\u30A1\u30A4\u30EB\u306C\u30EA\u30B9\u30C8\u3093\u304B\u3044\u3044\u308A\u3057\u30FC\u3089\u308A\u3084\u3073\u30FC\u3093\u3002
|
||||
tab3_Txt_EnteredAsMsg1=\u3046\u3093\u3058\u3087\u30FC\u6B21\u306C\u3050\u3068\u3045\u5165\u529B\u3055\u308A\u3084\u3073\u305F\u3093:
|
||||
tab3_Txt_EnteredAsMsg2=\u554F\u984C\u56DE\u907F\u3059\u3093\u304C\u30FC\u3001root \u306A\u3044\u304C\u3001\u304F\u306C\u30E6\u30FC\u30B6\u30FC\u3093\u304B\u3044\u300Cudev\u300D\u30EB\u30FC\u30EB\u8A2D\u5B9A\u3059\u308B\u3044\u308A\u3086\u30FC\u306C\u3042\u3044\u3073\u30FC\u3093\u3002
|
||||
tab3_Txt_FilesToUploadTitle=\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3059\u308B\u30D5\u30A1\u30A4\u30EB:
|
||||
tab3_Txt_GreetingsMessage=NS-USBloader\u3093\u304B\u3044\u3081\u3093\u305D\u30FC\u308C\u30FC
|
||||
tab3_Txt_NoFolderOrFileSelected=\u30D5\u30A1\u30A4\u30EB\u306C\u9078\u629E\u3055\u308A\u3084\u3073\u3089\u3093: \u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\u3059\u3057\u304C\u3042\u3044\u3073\u3089\u3093\u3002
|
||||
windowBodyConfirmExit=\u30C7\u30FC\u30BF\u8EE2\u9001\u306C\u9032\u884C\u4E2D\u3084\u3044\u3073\u30FC\u3093\u3002\u304F\u306C\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u304F\u30FC\u3044\u3093\u3067\u3043\u4E2D\u65AD\u3055\u308A\u3084\u3073\u30FC\u3093\u3002\n\u6700\u60AA\u306C\u4E8B\u614B\u3084\u3044\u3073\u30FC\u3093\u3002\n\u51E6\u7406\u4E2D\u65AD\u3057\u7D42\u4E86\u3055\u3073\u30FC\u304C?
|
||||
windowTitleConfirmExit=\u3046\u3045\u30FC\u3046\u3045\u30FC\u3001\u304F\u308A\u3055\u3093\u3050\u30FC\u3068\u3045\u30FC\u304F\u3043\u307F\u305D\u30FC\u308C\u30FC\uFF01
|
||||
btn_Stop=\u5272\u308A\u8FBC\u307F
|
||||
tab3_Txt_GreetingsMessage2=--\n\
|
||||
Source: https://git.redrise.ru/desu/ns-usbloader\n\
|
||||
Mirror: https://github.com/developersu/ns-usbloader/\n\
|
||||
Site: https://redrise.ru\n\
|
||||
Dmitry Isaenko [developer.su]
|
||||
tab1_table_Lbl_Status=\u30B9\u30C6\u30FC\u30BF\u30B9
|
||||
tab1_table_Lbl_FileName=\u30D5\u30A1\u30A4\u30EB\u540D
|
||||
tab1_table_Lbl_Size=\u30B5\u30A4\u30BA
|
||||
tab1_table_Lbl_Upload=\u30A2\u30C3\u30D7\u30ED\u30FC\u30C9\uFF1F
|
||||
tab1_table_contextMenu_Btn_BtnDelete=\u524A\u9664\u3059\u3093
|
||||
tab1_table_contextMenu_Btn_DeleteAll=\u307E\u3058\u308A\u524A\u9664\u3059\u3093
|
||||
tab2_Lbl_HostIP=\u30DB\u30B9\u30C8 IP
|
||||
tab1_Lbl_NSIP=NS IP:
|
||||
tab2_Cb_ValidateNSHostName=NS IP \u5165\u529B\u5E38\u306B\u691C\u8A3C\u3055\u3073\u30FC\u3093\u3002
|
||||
windowBodyBadIp=NS IP \u30A2\u30C9\u30EC\u30B9\u6B63\u3057\u304F\u5165\u529B\u3055\u3073\u305F\u304C?
|
||||
windowTitleBadIp=NS\u306CIP\u30A2\u30C9\u30EC\u30B9\u306C\u3070\u3063\u307A\u30FC\u3068\u30FC\u308B\u53EF\u80FD\u6027\u304C\u3042\u3044\u3073\u30FC\u3093
|
||||
tab2_Cb_ExpertMode=\u30A8\u30AD\u30B9\u30D1\u30FC\u30C8\u30E2\u30FC\u30C9 (NET \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7)
|
||||
tab2_Lbl_HostPort=\u30DD\u30FC\u30C8
|
||||
tab2_Cb_AutoDetectIp=IP\u306C\u81EA\u52D5\u691C\u51FA
|
||||
tab2_Cb_RandSelectPort=\u30E9\u30F3\u30C0\u30E0\u3093\u304B\u3044\u30DD\u30FC\u30C8\u53D6\u5F97
|
||||
tab2_Cb_DontServeRequests=\u30EA\u30AF\u30A8\u30B9\u30C8\u51E6\u7406\u3055\u3093
|
||||
tab2_Lbl_DontServeRequestsDesc=\u9078\u629E\u3057\u30FC\u306D\u30FC\u3001\u304F\u306C\u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u30FC NS (\u30CD\u30C3\u30C8\u7D4C\u7531) \u304B\u3089\u306C NSP \u30D5\u30A1\u30A4\u30EB\u8981\u6C42\u3093\u304B\u3044\u5FDC\u7B54\u3055\u3058\u3001\u5B9A\u7FA9\u3055\u3063\u305F\u308B\u30DB\u30B9\u30C8\u8A2D\u5B9A\u4F7F\u7528\u3057 Awoo \u30A4\u30F3\u30B9\u30C8\u30FC\u30E9 (\u3042\u3089\u3093\u3067\u3043\u4E92\u63DB\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3) \u3093\u304B\u3044\u30D5\u30A1\u30A4\u30EB\u304B\u3081\u30FC\u3044\u308B\u3070\u3059\u3061\u3066\u30FC\u3084\u3073\u30FC\u3093\u3002
|
||||
tab2_Lbl_HostExtra=\u30A8\u30AD\u30B9\u30C8\u30E9
|
||||
windowTitleErrorPort=\u30DD\u30FC\u30C8\u306C\u6B63\u3057\u304F\u8A2D\u5B9A\u3055\u308A\u3084\u3073\u3089\u3093!
|
||||
windowBodyErrorPort=\u30DD\u30FC\u30C8 0 \u3042\u3089\u3093\u3067\u3043 65535 \u3086\u308A\u307E\u304E\u304F\u3059\u3057\u3047\u30FC\u306A\u3084\u3073\u3089\u3093\u3002
|
||||
tab2_Cb_AutoCheckForUpdates=\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u306C\u81EA\u52D5\u30C1\u30A7\u30C3\u30AF
|
||||
windowTitleNewVersionAval=\u307F\u30FC\u3055\u308B\u30D0\u30FC\u30B8\u30E7\u30F3\u306C\u5229\u7528\u53EF\u80FD\u3084\u3044\u3073\u30FC\u3093
|
||||
windowTitleNewVersionNOTAval=\u307F\u30FC\u3055\u308B\u30D0\u30FC\u30B8\u30E7\u30F3\u30FC\u3042\u3044\u3073\u3089\u3093
|
||||
windowTitleNewVersionUnknown=\u307F\u30FC\u3055\u308B\u30D0\u30FC\u30B8\u30E7\u30F3\u78BA\u8A8D\u306A\u3084\u3073\u3089\u3093
|
||||
windowBodyNewVersionUnknown=\u554F\u984C\u304C\u767A\u751F\u3055\u3073\u305F\u3093\n\u30A4\u30F3\u30BF\u30FC\u30CD\u30C3\u30C8\u306C\u5229\u7528\u306A\u3089\u3093\u304C\u3001GitHub\u304C\u30C0\u30A6\u30F3\u305D\u30FC\u308B\u53EF\u80FD\u6027\u304C\u3042\u3044\u3073\u30FC\u3093
|
||||
windowBodyNewVersionNOTAval=\u6700\u65B0\u30D0\u30FC\u30B8\u30E7\u30F3\u4F7F\u7528\u305D\u30FC\u3044\u3073\u30FC\u3093
|
||||
tab2_Cb_AllowXciNszXcz=Awoo \u306C XCI / NSZ / XCZ \u30D5\u30A1\u30A4\u30EB\u306C\u9078\u629E\u8A31\u53EF
|
||||
tab2_Lbl_AllowXciNszXczDesc=XCI/NSZ/XCZ \u30B5\u30DD\u30FC\u30C8\u3057\u30FC\u3001Awoo (\u5225\u540D Adubbz/TinFoil) \u8EE2\u9001\u30D7\u30ED\u30C8\u30B3\u30EB\u5229\u7528\u3059\u308B\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u3063\u3057\u4F7F\u7528\u3055\u308A\u3084\u3073\u30FC\u3093\u3002 \u3086\u30FC\u308F\u304B\u3089\u3093\u3070\u30FC\u3084\u5909\u66F4\u3055\u3093\u3050\u30FC\u3068\u3045\u30FC\u304F\u3043\u307F\u305D\u30FC\u308C\u30FC\u3002 Awoo \u30A4\u30F3\u30B9\u30C8\u30FC\u30E9\u30FC\u6709\u52B9\u306A\u3055\u3073\u30FC\u3093\u3002
|
||||
tab2_Lbl_Language=\u8A00\u8A9E
|
||||
windowBodyRestartToApplyLang=\u5909\u66F4\u9069\u7528\u3059\u3093\u304C\u30FC\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u518D\u8D77\u52D5\u3057\u304F\u3043\u307F\u305D\u30FC\u308C\u30FC\u3002
|
||||
btn_OpenSplitFile=\u30B9\u30D7\u30EA\u30C3\u30C8ROM\u9078\u629E
|
||||
tab2_Lbl_ApplicationSettings=\u4E3B\u306A\u8A2D\u5B9A
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=\u30D5\u30A1\u30A4\u30EB\u306C\u5206\u5272\u3068\u3045\u7D50\u5408\u30C4\u30FC\u30EB
|
||||
tabSplMrg_RadioBtn_Split=\u30D5\u30A1\u30A4\u30EB\u306C\u5206\u5272\u3068\u3045\u7D50\u5408\u30C4\u30FC\u30EB
|
||||
tabSplMrg_RadioBtn_Merge=\u30DE\u30FC\u30B8
|
||||
tabSplMrg_Txt_File=\u30D5\u30A1\u30A4\u30EB\uFF1A
|
||||
tabSplMrg_Txt_Folder=\u5206\u5272\u30D5\u30A1\u30A4\u30EB (\u30D5\u30A9\u30EB\u30C0\u30FC):
|
||||
tabSplMrg_Btn_SelectFile=\u30D5\u30A1\u30A4\u30EB\u3044\u3089\u3076\u3093
|
||||
tabSplMrg_Btn_SelectFolder=\u30D5\u30A9\u30EB\u30C0\u30FC\u9078\u629E
|
||||
tabSplMrg_Lbl_SaveToLocation=\u3093\u304B\u3044\u4FDD\u5B58\uFF1A
|
||||
tabSplMrg_Btn_ChangeSaveToLocation=\u5909\u308F\u3044\u3093
|
||||
tabSplMrg_Btn_Convert=\u5909\u63DB
|
||||
windowTitleError=\u30A8\u30E9\u30FC
|
||||
windowBodyPleaseFinishTransfersFirst=\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3 USB/\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF \u30D7\u30ED\u30BB\u30B9\u306C\u30A2\u30AF\u30C6\u30A3\u30D6\u306A\u3070\u30FC\u3001\u30D5\u30A1\u30A4\u30EB\u5206\u5272/\u30DE\u30FC\u30B8\u306A\u3084\u3073\u3089\u3093\u3002 \u6700\u521D\u3093\u304B\u3044\u30A2\u30AF\u30C6\u30A3\u30D6\u306A\u8EE2\u9001\u4E2D\u65AD\u3057\u304F\u3043\u307F\u305D\u30FC\u308C\u30FC\u3002
|
||||
done_txt=\u3046\u308F\u3044\uFF01
|
||||
failure_txt=\u5931\u6557
|
||||
btn_Select=\u9078\u629E\u3059\u3093
|
||||
btn_InjectPayloader=\u30DA\u30A4\u30ED\u30FC\u30C9\u633F\u5165\u3059\u3093
|
||||
tabNXDT_Btn_Start=\u59CB\u307F\u30FC\u3093\uFF01
|
||||
tab2_Btn_InstallDrivers=\u30C9\u30E9\u30A4\u30D0\u30FC\u306C\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3068\u3045\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB
|
||||
windowTitleDownloadDrivers=\u30C9\u30E9\u30A4\u30D0\u30FC\u306C\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3068\u3045\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB
|
||||
windowBodyDownloadDrivers=\u30C9\u30E9\u30A4\u30D0\u30FC\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u305D\u30FC\u3044\u3073\u30FC\u3093 (libusbK v3.0.7.0)...
|
||||
btn_Cancel=\u30AD\u30E3\u30F3\u30BB\u30EB
|
||||
btn_Close=\u304F\u30FC\u3044\u3093
|
||||
tab2_Cb_GlVersion=Gold Leaf\u30D0\u30FC\u30B8\u30E7\u30F3
|
||||
tab2_Cb_GLshowNspOnly=GoldLeaf\u3067\u3043 *.nsp \u306C\u307F\u8868\u793A\u3055\u3073\u30FC\u3093\u3002
|
||||
windowBodyPleaseStopOtherProcessFirst=\u884C\u3059\u308B\u524D\u306B\u3001\u4ED6\u306C\u30A2\u30AF\u30C6\u30A3\u30D6\u306A\u30D7\u30ED\u30BB\u30B9\u505C\u6B62\u3057\u304F\u3043\u307F\u305D\u30FC\u308C\u30FC\u3002
|
||||
tab2_Cb_foldersSelectorForRoms=ROM \u500B\u5225\u306B\u9078\u629E\u3059\u308B\u306C\u3067\u30FC\u306A\u304F\u3001ROM \u30D5\u30A1\u30A4\u30EB\u306C\u3042\u308B\u30D5\u30A9\u30EB\u30C0\u9078\u629E\u3055\u3073\u30FC\u3093\u3002
|
||||
tab2_Cb_foldersSelectorForRomsDesc=[\u30B2\u30FC\u30E0] \u30BF\u30D6\u306C [\u30D5\u30A1\u30A4\u30EB\u9078\u629E] \u30DC\u30BF\u30F3\u306C\u52D5\u4F5C\u5909\u66F4: ROM \u30D5\u30A1\u30A4\u30EB 1 \u3061\u306A\u30FC\u9078\u629E\u3059\u308B\u4EE3\u308F\u308A\u3093\u304B\u3044\u3001\u30D5\u30A9\u30EB\u30C0\u30FC\u9078\u629E\u3057\u3001\u30B5\u30DD\u30FC\u30C8\u3055\u308A\u3068\u30FC\u308B\u307E\u3058\u308A\u306C\u30D5\u30A1\u30A4\u30EB\u4E00\u5EA6\u3093\u304B\u3044\u8FFD\u52A0\u306A\u3084\u3073\u30FC\u3093\u3002
|
||||
windowTitleAddingFiles=\u30D5\u30A1\u30A4\u30EB\u691C\u7D22\u305D\u30FC\u3044\u3073\u30FC\u3093...
|
||||
windowBodyFilesScanned=\u30B9\u30AD\u30E3\u30F3\u3055\u3063\u305F\u308B\u30D5\u30A1\u30A4\u30EB: %d\n\u8FFD\u52A0\u4E88\u5B9A: %d
|
||||
tab2_Lbl_AwooBlockTitle=Awoo\u30A4\u30F3\u30B9\u30C8\u30FC\u30E9\u30FC\u3068\u3045\u4E92\u63DB\u6027
|
||||
tabRcm_Lbl_Payload=\u30DA\u30A4\u30ED\u30FC\u30C9\uFF1A
|
||||
tabRcm_Lbl_FuseeGelee=Fus\u00E9e Gel\u00E9e RCM
|
|
@ -45,7 +45,7 @@ tab2_Cb_AllowXciNszXcz=Awoo \uC6A9 XCI / NSZ / XCZ \uD30C\uC77C \uC120\uD0DD \uD
|
|||
tab2_Lbl_AllowXciNszXczDesc=XCI / NSZ / XCZ\uB97C \uC9C0\uC6D0\uD558\uACE0 Tinfoil \uC804\uC1A1 \uD504\uB85C\uD1A0\uCF5C\uC744 \uD65C\uC6A9\uD558\uB294 \uC560\uD50C\uB9AC\uCF00\uC774\uC158\uC5D0\uC11C \uC0AC\uC6A9\uB429\uB2C8\uB2E4. \uD655\uC2E4\uD558\uC9C0 \uC54A\uC740 \uACBD\uC6B0 \uBCC0\uACBD\uD558\uC9C0 \uB9C8\uC2ED\uC2DC\uC624. Awoo \uC124\uCE58 \uD504\uB85C\uADF8\uB7A8\uC5D0 \uB300\uD574 \uD65C\uC131\uD654\uD569\uB2C8\uB2E4.
|
||||
tab2_Lbl_Language=\uC5B8\uC5B4
|
||||
windowBodyRestartToApplyLang=\uBCC0\uACBD \uC0AC\uD56D\uC744 \uC801\uC6A9\uD558\uB824\uBA74 \uC751\uC6A9 \uD504\uB85C\uADF8\uB7A8\uC744 \uB2E4\uC2DC \uC2DC\uC791\uD558\uC2ED\uC2DC\uC624.
|
||||
btn_OpenSplitFile=\uBD84\uD560 ROM \uC120\uD0DD
|
||||
btn_OpenSplitFile=\uBD84\uD560 NSP \uC120\uD0DD
|
||||
tab2_Lbl_ApplicationSettings=\uC8FC\uC694 \uC124\uC815
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=\uD30C\uC77C \uBD84\uD560 & \uBCD1\uD569 \uB3C4\uAD6C
|
||||
tabSplMrg_RadioBtn_Split=\uBD84\uD560
|
||||
|
@ -79,15 +79,4 @@ windowBodyFilesScanned=\uC2A4\uCE94 \uB41C \uD30C\uC77C: %d\n\uCD94\uAC00 \uB420
|
|||
tab2_Lbl_AwooBlockTitle=Awoo \uC124\uCE58 \uD504\uB85C\uADF8\uB7A8\uACFC \uD638\uD658\uC131
|
||||
tabRcm_Lbl_Payload=\uD398\uC774\uB85C\uB4DC:
|
||||
tabRcm_Lbl_FuseeGelee=Fus\u00E9e Gel\u00E9e RCM
|
||||
tabPatches_Lbl_Firmware=\uD38C\uC6E8\uC5B4:
|
||||
tabPatches_Lbl_Atmo=Atmosphere:
|
||||
tabPatches_Btn_fromFolder=\uD3F4\uB354\uC5D0\uC11C
|
||||
tabPatches_Btn_asZipFile=ZIP \uD30C\uC77C\uB85C
|
||||
tabPatches_Lbl_Title=\uD328\uCE58
|
||||
tabPatches_Lbl_Keys=\uD0A4:
|
||||
tabPatches_Btn_MakeEs=ES \uB9CC\uB4E4\uAE30
|
||||
tabPatches_Btn_MakeFs=FS \uB9CC\uB4E4\uAE30
|
||||
tabPatches_Btn_MakeAtmo=\uB85C\uB354 \uB9CC\uB4E4\uAE30 (Atmosphere)
|
||||
tabPatches_Btn_MakeAll=\uBAA8\uB450 \uB9CC\uB4E4\uAE30
|
||||
tabPatches_ServiceWindowMessageEsFs=\uD38C\uC6E8\uC5B4\uC640 \uD0A4 \uBAA8\uB450 \uD328\uCE58\uB97C \uC0DD\uC131\uD558\uB3C4\uB85D \uC124\uC815\uD574\uC57C \uD569\uB2C8\uB2E4. \uADF8\uB807\uC9C0 \uC54A\uC73C\uBA74 \uBB34\uC5C7\uC744 \uD328\uCE58\uD560\uC9C0 \uBA85\uD655\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||
tabPatches_ServiceWindowMessageLoader='\uB85C\uB354' \uD328\uCE58\uB97C \uC0DD\uC131\uD558\uB824\uBA74 Atmosphere \uD3F4\uB354\uB97C \uC815\uC758\uD574\uC57C \uD569\uB2C8\uB2E4.
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ tab2_Cb_AllowXciNszXcz=permitir arquivos XCI / NSZ / XCZ para o awoo
|
|||
tab2_Lbl_AllowXciNszXczDesc=Usado por aplica\u00E7\u00F5es que suportam XCI/NSZ/XCZ e utiliza protocolos de transfer\u00EAncia do Tinfoil. N\u00E3o mude o que n\u00E3o tem certeza. Ative para uso com o Awoo-Installer.
|
||||
tab2_Lbl_Language=Idioma
|
||||
windowBodyRestartToApplyLang=Por favor, reinicie para aplicar as modifica\u00E7\u00F5es.
|
||||
btn_OpenSplitFile=Select split file
|
||||
btn_OpenSplitFile=Select split NSP
|
||||
tab2_Lbl_ApplicationSettings=Configura\u00E7\u00F5es principais
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=Ferramenta de Fragmentar (Split) & Mesclar (Merge) arquivos
|
||||
tabSplMrg_RadioBtn_Split=Fragmentar (Dividir)
|
||||
|
|
|
@ -45,7 +45,7 @@ tab2_Cb_AllowXciNszXcz=Adaug\u0103 fi\u0219iere XCI / NSZ / XCZ pentru selec\u02
|
|||
tab2_Lbl_AllowXciNszXczDesc=Folosit de aplica\u021Bii care suport\u0103 XCI/NSZ/XCZ \u0219i folosesc protocolul de transfer al lui Tinfoil. Nu schimba dac\u0103\u00A0nu e\u0219ti sigur. Bifeaz\u0103 pentru Awoo Installer.
|
||||
tab2_Lbl_Language=Limb\u0103
|
||||
windowBodyRestartToApplyLang=Te rog restarteaz\u0103 aplica\u021Bia pentru a aplica set\u0103rile noi.
|
||||
btn_OpenSplitFile=Selecteaz\u0103 pentru ROM frac\u021Bionat
|
||||
btn_OpenSplitFile=Selecteaz\u0103 pentru NSP frac\u021Bionat
|
||||
tab2_Lbl_ApplicationSettings=Set\u0103ri principale
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=Unealt\u0103 pentru \u00EEmp\u0103r\u021Bire \u0219i lipire de fi\u0219iere
|
||||
tabSplMrg_RadioBtn_Split=\u00CEmparte
|
||||
|
|
|
@ -23,7 +23,7 @@ tab2_Lbl_HostIP=IP \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0430
|
|||
tab1_Lbl_NSIP=NS IP:
|
||||
tab2_Cb_ValidateNSHostName=\u0412\u0441\u0435\u0433\u0434\u0430 \u043F\u0440\u043E\u0432\u0435\u0440\u044F\u0442\u044C \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E\u0441\u0442\u044C NS IP.
|
||||
windowTitleBadIp=IP \u0430\u0434\u0440\u0435\u0441 NS \u043F\u043E\u0445\u043E\u0436\u0435 \u043D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u044B\u0439
|
||||
windowBodyBadIp=\u0412\u044B \u0443\u0432\u0435\u0440\u0435\u043D\u044B, \u0447\u0442\u043E IP \u0430\u0434\u0440\u0435\u0441 NS \u0432\u0432\u0435\u0434\u0451\u043D \u0431\u0435\u0437 \u043E\u0448\u0438\u0431\u043E\u043A?
|
||||
windowBodyBadIp=\u0412\u044B \u0443\u0432\u0435\u0440\u0435\u043D\u044B \u0447\u0442\u043E IP \u0430\u0434\u0440\u0435\u0441 NS \u0432\u0432\u0435\u0434\u0451\u043D \u0431\u0435\u0437 \u043E\u0448\u0438\u0431\u043E\u043A?
|
||||
tab2_Cb_ExpertMode=\u0420\u0435\u0436\u0438\u043C \u044D\u043A\u0441\u043F\u0435\u0440\u0442\u0430 (\u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u0441\u0435\u0442\u0438)
|
||||
tab2_Lbl_HostPort=\u043F\u043E\u0440\u0442
|
||||
tab2_Cb_AutoDetectIp=\u0410\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438 \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u044F\u0442\u044C IP
|
||||
|
@ -44,7 +44,7 @@ tab2_Lbl_AllowXciNszXczDesc=\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u04
|
|||
tab2_Lbl_Language=\u042F\u0437\u044B\u043A
|
||||
windowBodyRestartToApplyLang=\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u0435 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0447\u0442\u043E\u0431\u044B \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F \u0432\u0441\u0442\u0443\u043F\u0438\u043B\u0438 \u0432 \u0441\u0438\u043B\u0443.
|
||||
tab2_Cb_GLshowNspOnly=\u041E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u044C \u0438\u0441\u043A\u043B\u044E\u0447\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0444\u0430\u0439\u043B\u044B *.nsp \u0432 GoldLeaf.
|
||||
btn_OpenSplitFile=\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0440\u0430\u0437\u0431\u0438\u0442\u044B\u0439 \u0444\u0430\u0439\u043B
|
||||
btn_OpenSplitFile=\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0440\u0430\u0437\u0431\u0438\u0442\u044B\u0439 NSP
|
||||
tab2_Lbl_ApplicationSettings=\u041E\u0441\u043D\u043E\u0432\u043D\u044B\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=\u0423\u0442\u0438\u043B\u0438\u0442\u0430 \u0440\u0430\u0437\u0431\u0438\u0432\u043A\u0438 \u0438 \u0441\u043B\u0438\u044F\u043D\u0438\u044F \u0444\u0430\u0439\u043B\u043E\u0432
|
||||
tabSplMrg_Btn_Convert=\u041A\u043E\u043D\u0432\u0435\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C
|
||||
|
@ -77,21 +77,5 @@ windowBodyFilesScanned=\u0424\u0430\u0439\u043B\u043E\u0432 \u043F\u0440\u043E\u
|
|||
tab2_Lbl_AwooBlockTitle=Awoo Installer \u0438 \u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u044B\u0435
|
||||
tabRcm_Lbl_Payload=Payload:
|
||||
tabRcm_Lbl_FuseeGelee=Fus\u00E9e Gel\u00E9e RCM
|
||||
tabPatches_Btn_asZipFile=\u0432 \u0432\u0438\u0434\u0435 ZIP
|
||||
tabPatches_Btn_fromFolder=\u0418\u0437 \u043F\u0430\u043F\u043A\u0438
|
||||
tabPatches_Btn_MakeAll=\u0421\u0433\u0435\u043D\u0435\u0440\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0432\u0441\u0451
|
||||
tabPatches_Btn_MakeAtmo=\u0421\u0433\u0435\u043D\u0435\u0440\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0434\u043B\u044F Loader (Atmosphere)
|
||||
tabPatches_Btn_MakeEs=\u0421\u0433\u0435\u043D\u0435\u0440\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0434\u043B\u044F ES
|
||||
tabPatches_Btn_MakeFs=\u0421\u0433\u0435\u043D\u0435\u0440\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0434\u043B\u044F FS
|
||||
tabPatches_Lbl_Atmo=Atmosphere:
|
||||
tabPatches_Lbl_Firmware=\u041F\u0440\u043E\u0448\u0438\u0432\u043A\u0430:
|
||||
tabPatches_Lbl_Keys=\u041A\u043B\u044E\u0447\u0438:
|
||||
tabPatches_Lbl_Title=\u041F\u0430\u0442\u0447\u0438
|
||||
tabPatches_ServiceWindowMessageEsFs=\u0414\u043B\u044F \u0441\u043E\u0437\u0434\u0430\u043D\u0438\u044F \u043F\u0430\u0442\u0447\u0435\u0439 \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E \u0443\u043A\u0430\u0437\u0430\u0442\u044C \u043A\u0430\u043A \u043F\u0443\u0442\u044C \u043A \u043F\u0440\u043E\u0448\u0438\u0432\u043A\u0435, \u0442\u0430\u043A \u0438 \u043F\u0443\u0442\u044C \u043A \u0444\u0430\u0439\u043B\u0443 \u043A\u043B\u044E\u0447\u0435\u0439. \u0418\u043D\u0430\u0447\u0435 \u043D\u0435 \u043F\u043E\u043D\u044F\u0442\u043D\u043E \u0447\u0442\u043E \u0436\u0435 \u043F\u0430\u0442\u0447\u0438\u0442\u044C.
|
||||
tabPatches_ServiceWindowMessageLoader=\u0414\u043B\u044F \u0441\u043E\u0437\u0434\u0430\u043D\u0438\u044F \u043F\u0430\u0442\u0447\u0430 \u00ABLoader\u00BB \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E \u0443\u043A\u0430\u0437\u0430\u0442\u044C \u043F\u0443\u0442\u044C \u043A Atmosphere.
|
||||
tab2_Btn_ApplicationFont=\u0418\u0437\u043C\u0435\u043D\u0438\u0442\u044C \u0448\u0440\u0438\u0444\u0442 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F
|
||||
btn_ResetToDefaults=\u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C
|
||||
fontPreviewText=\u041F\u0440\u0438\u043C\u0435\u0440 \u0442\u0435\u043A\u0441\u0442\u0430
|
||||
fontSize=\u0420\u0430\u0437\u043C\u0435\u0440 \u0448\u0440\u0438\u0444\u0442\u043E\u0432:
|
||||
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ tab2_Cb_AllowXciNszXcz=Till\u00E5t val av XCI / NSZ / XCZ-filer f\u00F6r Awoo
|
|||
tab2_Lbl_AllowXciNszXczDesc=Anv\u00E4nds av program som har st\u00F6d f\u00F6r XCI/NSZ/XCZ och anv\u00E4nder Awoo (aka Adubbz/TinFoil) \u00F6verf\u00F6ringsprotokoll. \u00C4ndra inte om du \u00E4r os\u00E4ker. Aktivera f\u00F6r Awoo Installer.
|
||||
tab2_Lbl_Language=Spr\u00E5k
|
||||
windowBodyRestartToApplyLang=Starta om programmet f\u00F6r att verkst\u00E4lla \u00E4ndringar.
|
||||
btn_OpenSplitFile=V\u00E4lj delad ROM
|
||||
btn_OpenSplitFile=V\u00E4lj delad NSP
|
||||
tab2_Lbl_ApplicationSettings=Huvudinst\u00E4llningar
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=Verktyg f\u00F6r att dela upp och sl\u00E5 ihop filer
|
||||
tabSplMrg_RadioBtn_Split=Dela upp
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
btn_OpenFile=Dosya secimi
|
||||
btn_OpenFolders=Klasor secimi
|
||||
btn_Upload=NS'e yukle
|
||||
btn_OpenFolders_tooltip=Taranmasi icin bir klasor secin.\nBu klasor ve butun alt klasorleri taranacaktir.\nButun uyusan dosyalar listeye eklenecektir.
|
||||
tab3_Txt_EnteredAsMsg1=Olarak giris yaptiniz:
|
||||
tab3_Txt_EnteredAsMsg2=Bir cok hatadan kacinmak icin root olmaniz ya da bu kullanici icin 'udev' kurallarini ayarlamaniz gerekmektedir.
|
||||
tab3_Txt_FilesToUploadTitle=Yuklenecek dosyalar:
|
||||
tab3_Txt_GreetingsMessage= NS-USBloader'a Hos Geldiniz
|
||||
tab3_Txt_NoFolderOrFileSelected=Hicbir dosya secilmedi: hicbir sey yuklenmedi.
|
||||
windowBodyConfirmExit=Data transferi devam ediyor ve uygulamayi kapatmak bunu yarida kesecek.\nBu su an yapabileceginiz en kotu sey.\nIslemi yardida kes ve cik ?
|
||||
windowTitleConfirmExit=Hayir,Bunu yapma!
|
||||
btn_Stop=Hata
|
||||
tab3_Txt_GreetingsMessage2=--\n\
|
||||
Source: https://git.redrise.ru/desu/ns-usbloader\n\
|
||||
Mirror: https://github.com/developersu/ns-usbloader/\n\
|
||||
Site: https://redrise.ru\n\
|
||||
Dmitry Isaenko [developer.su]
|
||||
tab1_table_Lbl_Status=Durum
|
||||
tab1_table_Lbl_FileName=Dosya Ismi
|
||||
tab1_table_Lbl_Size=Boyut
|
||||
tab1_table_Lbl_Upload=Yukle?
|
||||
tab1_table_contextMenu_Btn_BtnDelete=Kaldir
|
||||
tab1_table_contextMenu_Btn_DeleteAll=Hepsini kaldir
|
||||
tab2_Lbl_HostIP=Host IP
|
||||
tab1_Lbl_NSIP=NS IP:
|
||||
tab2_Cb_ValidateNSHostName= NS IP girislerinizi her zaman dogrulayin.
|
||||
windowBodyBadIp=Girilen NS IP adresinin dogru olduguna emin misiniz?
|
||||
windowTitleBadIp=NS'in IP adressi buyuk ihtimalle yanlis
|
||||
tab2_Cb_ExpertMode=Uzman modu (NET setup)
|
||||
tab2_Lbl_HostPort=Port
|
||||
tab2_Cb_AutoDetectIp=Oto-Tespit IP
|
||||
tab2_Cb_RandSelectPort=Portu rastgele al
|
||||
tab2_Cb_DontServeRequests=Istekleri yerine getirme
|
||||
tab2_Lbl_DontServeRequestsDesc=Eger secili ise, bu bilgisayar NS'den (ag uzerinden) gelen NSP dosyalarinin isteklerine yanit vermez ve Awoo Installer'a (veya uyumlu uygulamalara) dosyalari nerede aramasi gerektigini soylemek icin tanimlanmis ana bilgisayar ayarlarini kullanir.
|
||||
tab2_Lbl_HostExtra=Ekstra
|
||||
windowTitleErrorPort=Port seti hatali!
|
||||
windowBodyErrorPort=Port 0 olamaz ve 65535'den buyuk olamaz.
|
||||
tab2_Cb_AutoCheckForUpdates=Guncellemeleri otomatik kontrol et
|
||||
windowTitleNewVersionAval=Yeni versiyon mevcut
|
||||
windowTitleNewVersionNOTAval=Yeni versiyon mevcut degil
|
||||
windowTitleNewVersionUnknown=Yeni versiyon kontrolu yapilamiyor
|
||||
windowBodyNewVersionUnknown=Bir sey ters gitti\nBelki internet yoktur ya da GitHub cokmustur
|
||||
windowBodyNewVersionNOTAval=En son versiyonu kullaniyorsunuz
|
||||
tab2_Cb_AllowXciNszXcz=XCI / NSZ / XCZ dosyalaninin Awoo icin seciminine izin ver.
|
||||
tab2_Lbl_AllowXciNszXczDesc=XCI/NSZ/XCZ'yi destekleyen uygulamalar tarafindan kullanilir ve Awoo (Adubbz/TinFoil olarak da bilinir) transfer protokolunu uygular. Emin degilseniz degistirmeyin. Installer icin AWOO'yu etkinlestirin.
|
||||
tab2_Lbl_Language=Dil
|
||||
windowBodyRestartToApplyLang=Lutfen degisikliklerin uygulanabilmesi icin uygulamayi yendiden baslatin.
|
||||
btn_OpenSplitFile=Bolme sec
|
||||
tab2_Lbl_ApplicationSettings=Ana ayarlar
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=Dosyalari bolme & birlestirme araci
|
||||
tabSplMrg_RadioBtn_Split=Ayir
|
||||
tabSplMrg_RadioBtn_Merge=Birlestir
|
||||
tabSplMrg_Txt_File=Dosya:
|
||||
tabSplMrg_Txt_Folder=Dosyayi ayir (klasor):
|
||||
tabSplMrg_Btn_SelectFile=Dosya sec
|
||||
tabSplMrg_Btn_SelectFolder=Klasor Sec
|
||||
tabSplMrg_Lbl_SaveToLocation=Buraya kaydet:
|
||||
tabSplMrg_Btn_ChangeSaveToLocation=Degistir
|
||||
tabSplMrg_Btn_Convert=Cevir
|
||||
windowTitleError=Hata
|
||||
windowBodyPleaseFinishTransfersFirst=Bolme/Birlestirme islemleri USB/Network transfer sureci aktifken yapilamaz. Lutfen once aktif transfer isleminizi bitiriniz.
|
||||
done_txt=Hazir!
|
||||
failure_txt=Basarisiz
|
||||
btn_Select=Secim yap
|
||||
btn_InjectPayloader=payload yukle (enject)
|
||||
tabNXDT_Btn_Start=Basla!
|
||||
tab2_Btn_InstallDrivers=Suruculeri indir ve yukle
|
||||
windowTitleDownloadDrivers=Suruculeri indir ve yukle
|
||||
windowBodyDownloadDrivers=Suruculer indiriliyor (libusbK v3.0.7.0)...
|
||||
btn_Cancel=Iptal
|
||||
btn_Close=Kapat
|
||||
tab2_Cb_GlVersion=GoldLeaf versiyonu
|
||||
tab2_Cb_GLshowNspOnly=Goldleaf'ta sadece *.nsp goster.
|
||||
windowBodyPleaseStopOtherProcessFirst=Lutfen devam etmeden once butun diger aktif islemleri durdurun.
|
||||
tab2_Cb_foldersSelectorForRoms=Direkt ROM dosyalini secmek yerine ROM klasorunu sec
|
||||
tab2_Cb_foldersSelectorForRomsDesc=Oyunlar' sekmesinde 'Dosyalari Sec' dugmesi davranisini degistirir: Tek tek ROM dosyalarini secmek yerine, desteklenen her dosyayi bir klasor secerek ekleyebilirsiniz.
|
||||
windowTitleAddingFiles=Dosyalar araniyor...
|
||||
windowBodyFilesScanned=Dosyalar tarandi: %d\nEklenecek: %d
|
||||
tab2_Lbl_AwooBlockTitle=Awoo Yukleyicisi ve Uyumu
|
||||
tabRcm_Lbl_Payload=Payload:
|
||||
tabRcm_Lbl_FuseeGelee=Fus\u00E9e Gel\u00E9e RCM
|
||||
tabPatches_Lbl_Firmware=Firmware:
|
||||
tabPatches_Lbl_Atmo=Atmosphere:
|
||||
tabPatches_Btn_fromFolder=Klasorden
|
||||
tabPatches_Btn_asZipFile=ZIP dosyasi olarak
|
||||
tabPatches_Lbl_Title=Yamalar
|
||||
tabPatches_Lbl_Keys=Anahtarlar:
|
||||
tabPatches_Btn_MakeEs=ES yap
|
||||
tabPatches_Btn_MakeFs=FS yap
|
||||
tabPatches_Btn_MakeAtmo=Loader yap (Atmosphere)
|
||||
tabPatches_Btn_MakeAll=Hepsini yap
|
||||
tabPatches_ServiceWindowMessageEsFs=Firmware ve anahtarlar, yamalari olusturmak icin ayarlanmalidir. Aksi takdirde, neyi duzeltecegi belirsiz olacaktir.
|
||||
tabPatches_ServiceWindowMessageLoader='Loader' yamasi olusturmak icin Atmosphere klasoru tanimlanmalidir.
|
||||
tab2_Btn_ApplicationFont=Uygulama yazi tipini degistir
|
||||
btn_ResetToDefaults=Reset
|
||||
fontPreviewText=Yazi Onizlemesi
|
||||
fontSize=Yazi boyutu:
|
|
@ -44,7 +44,7 @@ tab2_Lbl_AllowXciNszXczDesc=\u0412\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u04
|
|||
tab2_Lbl_Language=\u041C\u043E\u0432\u0430
|
||||
windowBodyRestartToApplyLang=\u0411\u0443\u0434\u044C \u043B\u0430\u0441\u043A\u0430, \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0456\u0442\u044C \u0434\u043E\u0434\u0430\u0442\u043E\u043A \u0449\u043E\u0431 \u0437\u043C\u0456\u043D\u0438 \u0432\u0441\u0442\u0443\u043F\u0438\u043B\u0438 \u0432 \u0441\u0438\u043B\u0443.
|
||||
tab2_Cb_GLshowNspOnly=\u0412\u0456\u0434\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u0438 \u0432\u0438\u043A\u043B\u044E\u0447\u043D\u043E *.nsp \u0444\u0430\u0439\u043B\u0438 \u0443 GoldLeaf.
|
||||
btn_OpenSplitFile=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0440\u043E\u0437\u0431\u0438\u0442\u0438\u0439 \u0444\u0430\u0439\u043B
|
||||
btn_OpenSplitFile=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0440\u043E\u0437\u0431\u0438\u0442\u0438\u0439 NSP
|
||||
tab2_Lbl_ApplicationSettings=\u041E\u0441\u043D\u043E\u0432\u043D\u0456 \u043D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F
|
||||
tabSplMrg_Lbl_SplitNMergeTitle=\u041F\u043E\u043C\u0456\u0447\u043D\u0438\u043A \u0440\u043E\u0437\u0431\u0432\u043A\u0438 \u0442\u0430 \u043E\u0431'\u0454\u0434\u043D\u0430\u043D\u043D\u044F \u0444\u0430\u0439\u043B\u0456\u0432
|
||||
tabSplMrg_Btn_Convert=\u041A\u043E\u043D\u0432\u0435\u0440\u0442\u0443\u0432\u0430\u0442\u0438
|
||||
|
@ -77,20 +77,4 @@ windowBodyFilesScanned=\u0424\u0430\u0439\u043B\u0456\u0432 \u043F\u0440\u043E\u
|
|||
tab2_Lbl_AwooBlockTitle=Awoo Installer \u0442\u0430 \u0441\u0443\u043C\u0456\u0441\u043D\u0456
|
||||
tabRcm_Lbl_Payload=Payload:
|
||||
tabRcm_Lbl_FuseeGelee=Fus\u00E9e Gel\u00E9e RCM
|
||||
tabPatches_Btn_asZipFile=\u044F\u043A ZIP
|
||||
tabPatches_Btn_fromFolder=\u0417 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0456\u0457
|
||||
tabPatches_Btn_MakeAll=\u0421\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \u0432\u0441\u0456
|
||||
tabPatches_Btn_MakeAtmo=\u0421\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \u0434\u043B\u044F Loader (Atmosphere)
|
||||
tabPatches_Btn_MakeEs=\u0421\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \u0434\u043B\u044F ES
|
||||
tabPatches_Btn_MakeFs=\u0421\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \u0434\u043B\u044F FS
|
||||
tabPatches_Lbl_Atmo=Atmosphere:
|
||||
tabPatches_Lbl_Firmware=\u041F\u0440\u043E\u0448\u0438\u0432\u043A\u0430:
|
||||
tabPatches_Lbl_Keys=\u041A\u043B\u044E\u0447\u0456:
|
||||
tabPatches_Lbl_Title=\u041F\u0430\u0442\u0447\u0438
|
||||
tabPatches_ServiceWindowMessageEsFs=\u0414\u043B\u044F \u0441\u0442\u0432\u043E\u0440\u0435\u043D\u043D\u044F \u043F\u0430\u0442\u0447\u0456\u0432 \u043D\u0435\u043E\u0431\u0445\u0456\u0434\u043D\u043E \u0432\u043A\u0430\u0437\u0430\u0442\u0438 \u044F\u043A \u0448\u043B\u044F\u0445 \u0434\u043E \u043F\u0440\u043E\u0448\u0438\u0432\u043A\u0438, \u0442\u0430\u043A \u0456 \u0434\u043E \u0444\u0430\u0439\u043B\u0443 \u043A\u043B\u044E\u0447\u0456\u0432. \u0411\u043E \u0456\u043D\u0430\u043A\u0448\u0435 \u043D\u0435 \u0437\u0440\u043E\u0437\u0443\u043C\u0456\u043B\u043E \u0449\u043E \u0436 \u0442\u0440\u0435\u0431\u0430 \u043F\u0430\u0442\u0447\u0438\u0442\u0438.
|
||||
tabPatches_ServiceWindowMessageLoader=\u0414\u043B\u044F \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0456\u0457 "Loader"-\u043F\u0430\u0442\u0447\u0443 \u043D\u0435\u043E\u0431\u0445\u0456\u0434\u043D\u043E \u0432\u043A\u0430\u0437\u0430\u0442\u0438 \u0448\u043B\u044F\u0445 \u0434\u043E Atmosphere.
|
||||
tab2_Btn_ApplicationFont=\u0417\u043C\u0456\u043D\u0438\u0442\u0438 \u0448\u0440\u0438\u0444\u0442 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0438
|
||||
btn_ResetToDefaults=C\u043A\u0438\u043D\u0443\u0442\u0438
|
||||
fontPreviewText=\u041F\u0440\u0438\u043A\u043B\u0430\u0434 \u0442\u0435\u043A\u0441\u0442\u0443
|
||||
fontSize=\u0420\u043E\u0437\u043C\u0456\u0440 \u0448\u0440\u0438\u0444\u0442\u0456\u0432:
|
||||
|