Compare commits

...

102 Commits
v5.1 ... master

Author SHA1 Message Date
Dmitry Isaenko 5ee9f6aacd
Merge pull request #160 from secretjupiter/patch-1
continuous-integration/drone Build is passing Details
Added mandatory info to README.md for Apple Silicon users
2024-02-07 13:07:53 +03:00
Dmitry Isaenko 7f9b3a7598
Merge pull request #161 from Erimsaholut/master
Turkish Lang file
2024-02-07 13:07:24 +03:00
01ut cd9e3ddf30
Turkish Lang file
I just upload the .properties file
2024-02-03 16:05:11 +03:00
Kevin | Secret Jupiter d1ac1f5403
Added mandatory info to README.md for Apple Silicon users
Added mandatory info for Apple Silicon users
2024-01-28 22:00:45 +01:00
Dmitry Isaenko e9b0fa309e Merge remote-tracking branch 'origin/master'
continuous-integration/drone Build is passing Details
2023-12-26 14:39:31 +03:00
Dmitry Isaenko c0bf247666 Bundle drivers to windows installer #156 2023-12-26 14:39:05 +03:00
Dmitry Isaenko 66758ffdb9
Merge pull request #154 from justindhillon/broken-links
Fix Broken Links
2023-11-15 18:01:36 +03:00
Justin Dhillon b32986682e revert maven.apache.org link 2023-11-11 12:49:17 -08:00
Justin Dhillon 2935d4ef55 revert broken link 2023-11-11 12:48:21 -08:00
Justin Dhillon 353b058388 revert Swarsele 2023-11-08 09:13:44 -08:00
Justin Dhillon 5b3ea13b08 revert Stephane Meden (JackFromNice) 2023-11-08 09:12:22 -08:00
Justin Dhillon 1251d39a6b revert Adubbz/Tinfoil 2023-11-08 09:11:36 -08:00
Justin Dhillon 57e7f72531
Merge branch 'developersu:master' into broken-links 2023-11-08 09:08:38 -08:00
Dmitry Isaenko 88ca0815ed Properly disable integration tests
continuous-integration/drone/push Build is passing Details
2023-11-08 15:08:24 +03:00
Dmitry Isaenko 66e7338fa5 Save few integration tests
continuous-integration/drone/push Build is failing Details
2023-11-08 14:35:15 +03:00
Dmitry Isaenko fa236cb1ad Correct Goldleaf supported versions list 2023-11-08 14:34:00 +03:00
Justin Dhillon 5b120204ef fixed broken link 2023-11-07 10:10:24 -08:00
Justin Dhillon 94ad332bf7 fixed broken link to maven.apache.org/POM/4.0.0 2023-11-07 10:05:17 -08:00
Justin Dhillon b89bfa806d fixed broken link to github user developersu 2023-11-07 09:59:17 -08:00
Justin Dhillon abf7621f28 github account does not exist anymore, so I replaced the link with instagram 2023-11-07 09:57:50 -08:00
Justin Dhillon c5688f79df replaced missing github repo link with link to creator 2023-11-07 09:56:31 -08:00
Justin Dhillon 25910ac94c fixed broken website link 2023-11-07 09:55:05 -08:00
Justin Dhillon 474f90a427 replaced 404 github link to twitter profile 2023-11-07 09:52:55 -08:00
Dmitry Isaenko 8348c9f2ab Correct 'Font settings' window size.
continuous-integration/drone/push Build is passing Details
2023-10-30 00:09:27 +03:00
Dmitry Isaenko 47045b2aeb correct version
continuous-integration/drone/push Build is passing Details
2023-10-29 06:29:33 +03:00
Dmitry Isaenko 67351642ae Merge remote-tracking branch 'origin/master'
continuous-integration/drone Build is failing Details
2023-10-29 06:16:10 +03:00
Dmitry Isaenko 3909371774 Add fonts selector for #153 2023-10-29 06:15:43 +03:00
Dmitry Isaenko 1e4593afb6
Merge pull request #145 from DDinghoya/patch-7
continuous-integration/drone/push Build is passing Details
Update locale_ko_KR.properties
2023-06-02 15:54:55 +03:00
DDinghoya d3faa384ae
Update locale_ko_KR.properties 2023-05-30 23:32:29 +09:00
Dmitry Isaenko 9d4cac26e5
Merge pull request #144 from requinDr/patch-1
continuous-integration/drone/push Build is passing Details
Update locale_fr_FR.properties
2023-05-17 16:32:32 +03:00
requinDr ad211cd562
\N -> \n 2023-05-17 00:16:11 +02:00
requinDr 4bdc5ffb63
Update locale_fr_FR.properties
Add missings translations and missing accents to French (note that a few translations are still missing)
2023-05-17 00:14:00 +02:00
Dmitry Isaenko 7db7af0cf8
Merge pull request #140 from exiori/patch-1
continuous-integration/drone/push Build is passing Details
Update locale_zh_CN.properties
2023-04-15 14:24:13 +03:00
exiori 6052d385d9
Update locale_zh_CN.properties 2023-04-15 17:00:46 +08:00
exiori f6b875af0b
Update locale_zh_CN.properties
Update Dialog Tips
2023-04-05 10:58:17 +08:00
Dmitry Isaenko 01a25f071a Make CI output a bit more verbose
continuous-integration/drone/push Build is passing Details
2023-03-17 04:27:09 +03:00
Dmitry Isaenko c1651e874b Correct AppPreferences class. Fix #139
continuous-integration/drone/push Build is passing Details
2023-03-17 04:00:48 +03:00
Dmitry Isaenko 94845c1411 readme update
continuous-integration/drone/push Build is passing Details
2023-03-09 04:12:28 +03:00
Dmitry Isaenko 7cf3970aa7 Fix CI
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2023-02-10 21:23:22 +03:00
Dmitry Isaenko 5b69435e89 Setup builds for M1
continuous-integration/drone/push Build is failing Details
2023-02-10 21:09:26 +03:00
Dmitry Isaenko b463a63180 Fix 'class file version' mismatch. Aligned to Java11
continuous-integration/drone/push Build is passing Details
2023-02-10 03:15:58 +03:00
Dmitry Isaenko cbb9fd60b9 Correct CSS
continuous-integration/drone/push Build is passing Details
2023-02-09 18:16:10 +03:00
Dmitry Isaenko 5f0278fc7b Fix pom.xml
continuous-integration/drone/push Build is passing Details
2023-02-09 17:22:22 +03:00
Dmitry Isaenko 3981d0d8ca Merge remote-tracking branch 'origin/master'
continuous-integration/drone/push Build is passing Details
2023-02-09 15:26:32 +03:00
Dmitry Isaenko 29f29b7d31 Minor fixes 2023-02-09 15:25:13 +03:00
Dmitry Isaenko 38f495ebc1 Correct pom.xml
continuous-integration/drone/push Build is passing Details
2023-02-08 17:43:38 +03:00
Dmitry Isaenko 4d7c6f6ef1 Merge remote-tracking branch 'origin/master'
continuous-integration/drone/push Build is passing Details
2023-02-08 02:31:05 +03:00
Dmitry Isaenko 7f01805cd5 Fix CI+3: Append timestamps to installer artifact
continuous-integration/drone/push Build is passing Details
2023-02-08 02:21:55 +03:00
Dmitry Isaenko f82275e82d Fix CI+2
continuous-integration/drone/push Build is passing Details
2023-02-08 01:58:27 +03:00
Dmitry Isaenko 2356bfe0e9 Fix CI+1
continuous-integration/drone/push Build is failing Details
2023-02-08 01:50:27 +03:00
Dmitry Isaenko fc02a8af6b Fix CI
continuous-integration/drone/push Build is failing Details
2023-02-08 01:32:45 +03:00
Dmitry Isaenko c408f70b79 Switch to Java 11. Add win installer
continuous-integration/drone/push Build is failing Details
2023-02-08 01:15:30 +03:00
Dmitry Isaenko c39a5f4c5b Correct Java 8 related things
continuous-integration/drone/push Build is passing Details
2023-02-07 00:05:13 +03:00
Dmitry Isaenko ffa9c6903f https for secure!
continuous-integration/drone/push Build is passing Details
2023-02-06 16:21:11 +03:00
Dmitry Isaenko c34531a92f Fix dependencies resolution
continuous-integration/drone/push Build is passing Details
2023-02-06 16:16:03 +03:00
Dmitry Isaenko 83695511d3 Hide 'extended network settings' instead of setting it disabled
continuous-integration/drone/push Build is passing Details
2023-02-06 02:00:05 +03:00
Dmitry Isaenko c84f70ec10 "Installs Split NSP/XCI/NSZ/XCZ over Lan or USB", not only NSP. Also breaking every locale
continuous-integration/drone/push Build is passing Details
2023-02-04 17:05:57 +03:00
Dmitry Isaenko 6c51b8e1b6 Corrections at front and back end
continuous-integration/drone/push Build is passing Details
2023-02-04 15:25:34 +03:00
Dmitry Isaenko f8b60af41b FS drafts
continuous-integration/drone/push Build is passing Details
2023-02-01 12:44:45 +03:00
Dmitry Isaenko 4ccf833aa5 Fix issue where version was not showing in CLI mode; clear locale_en_US since it's just placeholder
continuous-integration/drone/push Build is passing Details
2022-12-26 07:59:56 +03:00
Dmitry Isaenko a60d929dcd Update readme
continuous-integration/drone/push Build is passing Details
2022-12-23 21:53:34 +03:00
Dmitry Isaenko 338bb699d1 Another one build-system-related fix
continuous-integration/drone/push Build is passing Details
2022-12-23 07:47:10 +03:00
Dmitry Isaenko 115625e3a3 Correct drone config to archive Launch4j artifact
continuous-integration/drone/push Build is failing Details
2022-12-23 07:22:24 +03:00
Dmitry Isaenko 55df39923f Correct readme, update few icons, add freedesktop entry and svg icon. Could be useful for packagers.
continuous-integration/drone/push Build is failing Details
2022-12-23 07:08:22 +03:00
Dmitry Isaenko 8b23b8967b Correct locales logic to get some kind of ISO 639-3 support, update pom, make ja_ryu appear (unfortunately as 'Japanese' language and not as 'Central Okinawan')
continuous-integration/drone/push Build is passing Details
2022-10-11 17:04:55 +03:00
Dmitry Isaenko 9aa4551ef0
Merge pull request #130 from kuragehimekurara1/master
continuous-integration/drone/push Build is passing Details
Added Japanese translation and Ryukyuan language translation
2022-10-11 15:17:12 +03:00
kuragehime 610d04c9bd
Update locale_ja_ryu.properties 2022-10-08 03:24:08 +09:00
kuragehime 9b02750dd3
Update locale_ja_ryu.properties 2022-10-08 03:10:04 +09:00
kuragehime 89dd6fdbe0
Update locale_ja_JP.properties 2022-10-08 02:53:51 +09:00
kuragehime b75421bc9e
Update locale_ja_ryu.properties 2022-10-08 01:35:32 +09:00
kuragehime cc09128373
Update locale_ja_JP.properties 2022-10-08 01:02:16 +09:00
kuragehime 6244fd974a
Update locale_ja_JP.properties 2022-10-07 01:35:21 +09:00
kuragehime 2edea43d63
Create locale_ja_ryu.properties 2022-10-06 17:13:01 +09:00
kuragehime c9dbb37c14
Create locale_ja_JP.properties 2022-10-06 17:06:49 +09:00
Dmitry Isaenko 51a3b1e7a1 Update pom
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2022-09-25 00:28:58 +03:00
Dmitry Isaenko 182c5293b5 Add Swedish translation kindly prepared by @yeager
continuous-integration/drone Build is passing Details
2022-08-22 20:26:10 +03:00
Dmitry Isaenko 38af160ae7 small readme adjustments
continuous-integration/drone/push Build is passing Details
2022-08-13 17:07:17 +03:00
Dmitry Isaenko edc27d6db0
Merge pull request #126 from DDinghoya/patch-6
continuous-integration/drone/push Build is passing Details
Update locale_ko_KR.properties
2022-08-05 22:06:08 +03:00
DDinghoya d08993be17
Update locale_ko_KR.properties 2022-08-05 22:36:58 +09:00
Dmitry Isaenko bc2cf44a97 Update build hacks
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2022-08-02 21:46:36 +03:00
Dmitry Isaenko eefaa70f95 fix yaml
continuous-integration/drone/push Build is passing Details
2022-07-26 20:16:01 +03:00
Dmitry Isaenko 5ed2167e9d Add Goldleaf v0.10 support. Remove jenkins malware, add Drone, update readme, increment version. Shifting code to the safer place. Update dependencies.
continuous-integration/drone Build encountered an error Details
Fix #94: Just doing as @Fatih120 said
Fix #124: Implement updated Spanish translation by @Uzi-Oni
2022-07-26 18:25:26 +03:00
Dmitry Isaenko 0b8092077a Remove paypal and liberapay out of the 'donations' section. I don't know if I can tell names of the people who decided to support this project by donations, but anyway: Dear ap*** R** and Ku**** A********, I highly appreciate your participation and want to assure you that all funding this project received will go to one of the local charity funds. Thank you both! 2022-03-15 03:01:51 +03:00
Dmitry Isaenko 5f03939b91 Update README.md 2022-03-01 16:06:55 +03:00
Dmitry Isaenko 503edcd127
Merge pull request #110 from DDinghoya/patch-5
Update locale_ko_KR.properties
2021-11-15 17:41:23 +03:00
DDinghoya ac3c0a3698
Update locale_ko_KR.properties 2021-11-13 10:11:32 +09:00
Dmitry Isaenko 0fab994a45
Merge pull request #106 from exiori/master
Create locale_zh_CN.properties
2021-09-23 05:14:30 +03:00
exiori 5b67821d3b
Create locale_zh_CN.properties
Update  a line
2021-09-22 10:03:30 +08:00
Dmitry Isaenko 8547eb0e4e Polish README.md 2021-09-21 01:42:13 +03:00
Dmitry Isaenko a6f95f32bb
Merge pull request #105 from qazrfv1234/qazrfv1234-patch-1
Update locale_zh_TW.properties
2021-09-21 01:16:34 +03:00
qazrfv1234 eb72fd17b6
Update locale_zh_TW.properties 2021-09-16 21:46:44 +08:00
Dmitry Isaenko f0714ef961 And I forgot to update screenshot. Here. 2021-09-16 01:00:05 +03:00
Dmitry Isaenko 9301f4da8e update README 2021-09-16 00:54:42 +03:00
Dmitry Isaenko 2ee0362980 Move to OpenJFX 17 2021-09-16 00:51:02 +03:00
Dmitry Isaenko ff77c117ad Add libusb4java.dylib that @agungrbudiman gave me. 2021-09-05 02:57:08 +03:00
Dmitry Isaenko 325b7fa32a
Merge pull request #104 from exiori/master
update chinsee translation
2021-08-28 15:16:35 +03:00
exiori 3fde307ea1
Update chinese translation 2021-08-28 11:27:45 +08:00
exiori c5e8dc67ad
Update chinese translation 2021-08-28 11:24:50 +08:00
exiori 66f4c22417
Update Chinese(Traditional)by FFT9 2021-08-28 11:18:08 +08:00
exiori b5a6972671
Update Chinese (Simplified) by FFT9 2021-08-28 09:25:10 +08:00
exiori 7d8b32dc7c
Add and Update simChinese list by FFT9 2021-08-28 09:22:02 +08:00
Dmitry Isaenko 8af1aa485e Fix #102 2021-08-27 18:35:53 +03:00
104 changed files with 7862 additions and 687 deletions

101
.drone.yml Normal file
View File

@ -0,0 +1,101 @@
kind: pipeline
type: docker
name: default
steps:
- name: test
image: maven:3-openjdk-17
commands:
- mvn -B -DskipTests clean package
- mvn test -B
volumes:
- name: m2
path: /root/.m2
- name: archive-standard-artifact
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
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
path: /root/.m2
- name: builds
path: /builds
volumes:
- name: m2
host:
path: /home/docker/drone/files/m2
- 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 Normal file
View File

@ -0,0 +1,2 @@
offsets.txt
environment.txt

3
.make_legacy Normal file
View File

@ -0,0 +1,3 @@
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 Normal file
View File

@ -0,0 +1,5 @@
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

31
Jenkinsfile vendored
View File

@ -1,31 +0,0 @@
pipeline {
agent {
docker {
image 'maven:3-jdk-11'
args '-v /home/docker/jenkins/files/m2:/root/.m2'
}
}
stages {
stage('Build') {
steps {
sh 'mvn -B -DskipTests clean package'
}
post {
success {
archiveArtifacts artifacts: 'target/*.jar, target/*.exe'
}
}
}
stage('Test') {
steps {
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}
}
}

120
README.md
View File

@ -1,12 +1,11 @@
# NS-USBloader
<h1 align="center"><img src="screenshots/ApplicationLogo.svg" alt="NS-USBloader" width="450px"/></h1>
![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) ![CI](https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fredrise.ru%2Fjen%2Fjob%2Fns-usbloader%2Fjob%2Fmaster%2F)
[Support author](#support-this-app)
![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**.
* This application also could be used as RCM payload on Windows, MacOS and Linux (supported arch: x86, x86_64 and Raspberry Pi).
* 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!
* Also you can use it for merging split-files into one :)
@ -14,12 +13,18 @@ Alternative to default **usb_install_pc.py**, **remote_install_pc.py**, **GoldTr
[Click here for Android version ;)](https://github.com/developersu/ns-usbloader-mobile)
With GUI and cookies. Works on Windows, macOS and Linux.
### Let's stay in touch:
#### [→ Independent source code storage](https://git.redrise.ru/desu/ns-usbloader)
#### [→ Mirror, issues tracker, place to send PRs](https://github.com/developersu/ns-usbloader)
#### [→ Nightly builds](https://redrise.ru/builds/ns-usbloader/)
Sometimes I add new posts about this project [on my home page](https://developersu.blogspot.com/search/label/NS-USBloader).
[Support/Donate](#support-this-app)
![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"/>
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"/>
#### License
@ -36,35 +41,42 @@ Sometimes I add new posts about this project [on my home 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
* Chinese (Simplified) by [Huang YunKun (htynkn)](https://github.com/htynkn), [exiori](https://github.com/exiori)
* 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/)
* German by [Swarsele](https://github.com/Swarsele)
* Vietnamese by [Hai Phan Nguyen (pnghai)](https://github.com/pnghai)
* Czech by [Spenaat](https://github.com/spenaat)r
* Chinese (Traditional) by [qazrfv1234](https://github.com/qazrfv1234)
* 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
### System requirements
JRE/JDK 8u60 or higher for Windows
- JDK 11 for macOS and Linux
- libusb, if you have a Mac with Apple Silicon (install via `brew install libusb`)
JDK 11 for MacOS and Linux
### Supported GoldLeaf versions
| GoldLeaf version | NS-USBloader version |
| ---------------- | -------------------- |
### 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+ |
where '+' means 'any next NS-USBloader version'.
@ -74,8 +86,6 @@ Awoo Installer uses the same command-set (or 'protocol') to [Adubbz/Tinfoil](htt
A lot of other forks/apps uses the same command-set. To stop speculating about the name it's now called 'Awoo'. It WAS called 'TinFoil' before. Not any more.
Also, please go to 'Settings' tab of NS-USBloader after first installation and check 'Allow XCI / NSZ / XCZ files selection for Awoo' option. This installer can install not only NSPs but a way more formats!
### Usage
##### Linux:
@ -86,17 +96,17 @@ Also, please go to 'Settings' tab of NS-USBloader after first installation and c
3. Optional: add user to 'udev' rules to use NS not-from-root-account
```
root # vim /etc/udev/rules.d/99-NS.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="3000", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="3000", MODE="0666"
root # udevadm control --reload-rules && udevadm trigger
```
4. For RCM part
```
root # vim /etc/udev/rules.d/99-NS-RCM.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="0955", ATTRS{idProduct}=="7321", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0955", ATTRS{idProduct}=="7321", MODE="0666"
root # udevadm control --reload-rules && udevadm trigger
```
Please note: you may have to change 'plugdev' group from example above to the different one. It depends on you linux distro.
5. For HiDPI use scaling like `java -Dglass.gtk.uiScale=150% -jar application.jar`
##### Raspberry Pi
@ -112,19 +122,23 @@ Double-click on downloaded .jar file. Follow instructions. Or see 'Linux' sectio
Set 'Security & Privacy' settings if needed.
*Please note: JDK 11 is recommended for using on MacOS. There are few really weird issues already reported from JDK 14 users on Mac.*
*Please note: JDK 19 is recommended for using on macOS. There are issues already reported from users on Mac with JDK 14.*
##### macOS on Apple Silicon (ARM)
Download application with `-m1.jar` postfix.
Manually install libusb with Homebrew by running `brew install libusb` in your Terminal.
##### Windows:
* [Download and install Java JRE](http://java.com/download/) (8u60 or higher)
* Get this application (JAR file) and double-click on 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.
@ -134,19 +148,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
@ -162,7 +176,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.
@ -175,7 +189,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.
@ -206,7 +220,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
@ -217,9 +231,16 @@ $ 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.
usb4java since NS-USBloader-v0.2.3 switched to 1.2.0 instead of 1.3.0. This should not impact anyone except users of macOS High Sierra (and Sierra, and El Capitan) where previous versions of NS-USBloader didn't work. Now builds with usb4java-1.2.0 marked as '-legacy' and builds with usb4java-1.3.0 doesn't have postfixes.
#### 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 '-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
### Translators!
@ -231,18 +252,21 @@ To convert files of any locale to readable format (and vise-versa) you can use t
## Support this app
If you like this app, just give a star.
If you like this app, just give a star (@ GitHub).
If you want to make a donation*, please see below:
This is non-commercial project.
<a href="https://liberapay.com/developersu/donate"><img alt="Donate using Liberapay" src="https://liberapay.com/assets/widgets/donate.svg"></a>
Nevertheless, I'll be more than happy if you find a chance to make a donation for charity to people I trust:
<a href="https://paypal.me/developersu" title="PayPal"><img src="https://www.paypalobjects.com/webstatic/mktg/Logo/pp-logo-100px.png" border="0" alt="PayPal Logo" /></a>
* BTC → 1BnErE3n6LEdEjvvFrt4FMdXd1UGa5L7Ge
* ETH → 0x9c29418129553bE171181bb6245151aa0576A3b7
* DOT → 15BWSwmA4xEHZdq3gGftWg7dctMQk9vXwqA92Pg22gsxDweF
* LTC → ltc1qfjvzxm04tax077ra9rvmxdnsum8alws2n20fag
* ETC → 0xe9064De288C8454942533a005AB72515e689226E
* USDT (TRC20) → TKgp5SvJGiqYNFtvJfEDGLFbezFEHq1tBy
* USDT (ERC20) → 0x9c29418129553bE171181bb6245151aa0576A3b7
* XRP → rGmGaLsKmSUbxWfyi4mujtVamTzj3Nqxbw.
[yoomoney](https://yoomoney.ru/to/410014301951665)
*Please note: this is non-commercial application.
Thanks
Thanks!
Appreciate assistance and support of both [Vitaliy](https://github.com/SebastianUA) and [Konstantin](https://github.com/konstantin-kelemen). Without you all this magic would not have happened.

View File

@ -0,0 +1,9 @@
#!/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;

View File

@ -0,0 +1,118 @@
<?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>

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -0,0 +1,8 @@
#### 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'

View File

@ -0,0 +1,160 @@
;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

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

File diff suppressed because it is too large Load Diff

BIN
misc/windows/NSIS/logo.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

13
misc/windows/update_version.sh Executable file
View File

@ -0,0 +1,13 @@
#!/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

163
pom.xml
View File

@ -8,12 +8,10 @@
<name>NS-USBloader</name>
<artifactId>ns-usbloader</artifactId>
<version>5.1-SNAPSHOT</version>
<version>7.1</version> <!-- linked via script to NSIS system. Should have format of 2 blocks of numbers -->
<url>https://github.com/developersu/ns-usbloader/</url>
<description>
NSP USB loader for Awoo Installer and compatible (USB and Network) and GoldLeaf
</description>
<url>https://redrise.ru</url>
<description>NS multi-tool</description>
<inceptionYear>2019</inceptionYear>
<organization>
<name>Dmitry Isaenko</name>
@ -40,106 +38,96 @@
</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/developer_su/${project.artifactId}/issues</url>
<url>https://github.com/developersu/${project.artifactId}/issues</url>
</issueManagement>
<!-- openJFX Linux -->
<dependencies>
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.4</version>
<version>1.5.0</version>
<scope>compile</scope>
</dependency>
<!-- openJFX Linux -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>16</version>
<artifactId>javafx-graphics</artifactId>
<version>${javafx.version}</version>
<classifier>linux</classifier>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-media</artifactId>
<version>16</version>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
<classifier>linux</classifier>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>16</version>
<classifier>linux</classifier>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>16</version>
<version>${javafx.version}</version>
<classifier>linux</classifier>
<scope>compile</scope>
</dependency>
<!-- openJFX Windows -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>16</version>
<artifactId>javafx-graphics</artifactId>
<version>${javafx.version}</version>
<classifier>win</classifier>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-media</artifactId>
<version>16</version>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
<classifier>win</classifier>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>16</version>
<classifier>win</classifier>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>16</version>
<version>${javafx.version}</version>
<classifier>win</classifier>
<scope>compile</scope>
</dependency>
<!-- openJFX MAC -->
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>16</version>
<artifactId>javafx-graphics</artifactId>
<version>${javafx.version}</version>
<classifier>mac</classifier>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-media</artifactId>
<version>16</version>
<artifactId>javafx-controls</artifactId>
<version>${javafx.version}</version>
<classifier>mac</classifier>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>16</version>
<classifier>mac</classifier>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-graphics</artifactId>
<version>16</version>
<version>${javafx.version}</version>
<classifier>mac</classifier>
<scope>compile</scope>
</dependency>
@ -154,24 +142,53 @@
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.5.2</version>
<version>5.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.5.2</version>
<version>5.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.5.2</version>
<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>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources-filtered</directory>
<filtering>true</filtering>
</resource>
</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>
@ -186,16 +203,23 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<version>3.10.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<release>11</release>
</configuration>
</plugin>
<!-- Don't generate default JAR without dependencies -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<version>3.1.2</version>
<!--
<configuration>
<manifestEntries>
<Automatic-Module-Name>nsusbloader</Automatic-Module-Name>
</manifestEntries>
</configuration>
-->
<executions>
<execution>
<id>default-jar</id>
@ -217,6 +241,7 @@
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
@ -228,14 +253,13 @@
</execution>
</executions>
</plugin>
<!-- Launch4j
<plugin>
<groupId>com.akathist.maven.plugins.launch4j</groupId>
<version>1.7.25</version>
<version>2.2.0</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>
@ -243,34 +267,37 @@
<configuration>
<headerType>gui</headerType>
<icon>appicon.ico</icon>
<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>
<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> -->
<jre>
<minVersion>1.8</minVersion>
<path>%PWD%/jdk</path>
<minVersion>11.0.0</minVersion>
</jre>
<versionInfo>
<fileVersion>1.0.0.0</fileVersion>
<fileVersion>${project.version}.0.0</fileVersion>
<txtFileVersion>${project.version}</txtFileVersion>
<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>
<fileDescription>NS multi-tool</fileDescription>
<copyright>GNU General Public License v3, ${project.inceptionYear} ${project.organization.name}, Russia.</copyright>
<productVersion>${project.version}.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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -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="58.000351mm"
viewBox="0 0 132.50603 58.000351"
height="45.000351mm"
viewBox="0 0 132.50603 45.000351"
version="1.1"
id="svg8"
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
sodipodi:docname="Application Logo.svg">
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/">
<defs
id="defs2" />
<sodipodi:namedview
@ -23,28 +23,31 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4142136"
inkscape:cx="383.67648"
inkscape:cy="100.29922"
inkscape:zoom="4.0000001"
inkscape:cx="233.49999"
inkscape:cy="127.875"
inkscape:document-units="mm"
inkscape:current-layer="svg8"
inkscape:current-layer="flowRoot1022"
showgrid="false"
units="mm"
inkscape:window-width="1860"
inkscape:window-height="1058"
inkscape:window-x="1980"
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:document-rotation="0"
inkscape:showpageshadow="0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid829"
originx="-40.993969"
originy="-37.999746" />
originx="-40.99399"
originy="-37.999752" />
</sodipodi:namedview>
<metadata
id="metadata5">
@ -54,7 +57,6 @@
<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>
@ -114,145 +116,65 @@
inkscape:connector-curvature="0"
style="fill:#ffffff;stroke-width:0.0680452"
inkscape:label="usb_logo" />
<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"
<g
aria-label="NS-USBloader"
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>
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>
<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: 38 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -18,6 +18,8 @@
*/
package nsusbloader;
import javafx.scene.text.Font;
import java.util.Locale;
import java.util.prefs.Preferences;
@ -27,22 +29,26 @@ public class AppPreferences {
private final Preferences preferences;
private final Locale locale;
public static final String[] goldleafSupportedVersions = {"v0.5", "v0.7.x", "v0.8-0.9"};
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();
private AppPreferences(){
this.preferences = Preferences.userRoot().node("NS-USBloader");
String localeCode = preferences.get("locale", Locale.getDefault().toString());
this.locale = new Locale(localeCode.substring(0, 2), localeCode.substring(3, 5));
if (localeCode.length() < 5)
this.locale = new Locale("en", "EN");
else
this.locale = new Locale(localeCode.substring(0, 2), localeCode.substring(3));
}
public String getTheme(){
String theme = preferences.get("THEME", "/res/app_dark.css"); // Don't let user to change settings manually
String theme = preferences.get("THEME", "/res/app_dark.css"); // Don't let user 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 to change settings manually
int protocolIndex = preferences.getInt("protocol_index", 0); // Don't let user change settings manually
if (protocolIndex < 0 || protocolIndex > 1)
protocolIndex = 0;
return protocolIndex;
@ -50,7 +56,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 to change settings manually
String netUsb = preferences.get("NETUSB", "USB"); // Don't let user change settings manually
if (!netUsb.matches("(^USB$)|(^NET$)"))
netUsb = "USB";
return netUsb;
@ -114,7 +120,7 @@ public class AppPreferences {
public void setNspFileFilterGL(boolean prop){preferences.putBoolean("GL_NSP_FILTER", prop);}
public int getGlVersion(){
return preferences.getInt("gl_ver", goldleafSupportedVersions.length - 1);
return preferences.getInt("gl_ver", GOLDLEAF_SUPPORTED_VERSIONS.length - 1);
}
public void setGlVersion(int version){ preferences.putInt("gl_ver", version);}
@ -138,4 +144,28 @@ 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);
}
}

View File

@ -87,6 +87,7 @@ 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 ) );

View File

@ -0,0 +1,56 @@
/*
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();
}
}

View File

@ -0,0 +1,153 @@
/*
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.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.getInstance().updateApplicationFont(fontFamily, fontSize);
closeWindow();
}
private void closeWindow(){
((Stage) cancelBtn.getScene().getWindow()).close();
}
}

View File

@ -66,7 +66,7 @@ public class GamesController implements Initializable {
public NSTableViewController tableFilesListController; // Accessible from Mediator (for drag-n-drop support)
@FXML
private Button selectNspBtn, selectSplitNspBtn, uploadStopBtn;
private Button selectNspBtn, selectSplitBtn, uploadStopBtn;
private String previouslyOpenedPath;
private Region btnUpStopImage, btnSelectImage;
private ResourceBundle resourceBundle;
@ -141,8 +141,8 @@ public class GamesController implements Initializable {
this.btnSelectImage = new Region();
setFilesSelectorButtonBehaviour(preferences.getDirectoriesChooserForRoms());
selectSplitNspBtn.setOnAction(e-> selectSplitBtnAction());
selectSplitNspBtn.getStyleClass().add("buttonSelect");
selectSplitBtn.setOnAction(e-> selectSplitBtnAction());
selectSplitBtn.getStyleClass().add("buttonSelect");
uploadStopBtn.setOnAction(e-> uploadBtnAction());
uploadStopBtn.setDisable(isTinfoil());
@ -326,7 +326,7 @@ public class GamesController implements Initializable {
}
/**
* Functionality for selecting Split NSP button.
* Functionality for selecting Split-file button.
* */
private void selectSplitBtnAction(){
File splitFile;
@ -338,11 +338,28 @@ public class GamesController implements Initializable {
splitFile = dirChooser.showDialog(usbNetPane.getScene().getWindow());
if (splitFile != null && splitFile.getName().toLowerCase().endsWith(".nsp")) {
if (splitFile == null)
return;
int fileNameLen = splitFile.getName().length();
String fileExtension = splitFile.getName().toLowerCase().substring(fileNameLen-4, fileNameLen);
if (fileExtension.equals(".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
@ -456,7 +473,7 @@ public class GamesController implements Initializable {
}
selectNspBtn.setDisable(isActive);
selectSplitNspBtn.setDisable(isActive);
selectSplitBtn.setDisable(isActive);
btnUpStopImage.getStyleClass().clear();
if (isActive) {
@ -506,12 +523,12 @@ public class GamesController implements Initializable {
if (isDirectoryChooser){
selectNspBtn.setOnAction(e -> selectFoldersBtnAction());
btnSelectImage.getStyleClass().add("regionScanFolders");
selectSplitNspBtn.setVisible(false);
selectSplitBtn.setVisible(false);
}
else {
selectNspBtn.setOnAction(e -> selectFilesBtnAction());
btnSelectImage.getStyleClass().add("regionSelectFiles");
selectSplitNspBtn.setVisible(true);
selectSplitBtn.setVisible(true);
}
selectNspBtn.setGraphic(btnSelectImage);
}

View File

@ -43,7 +43,7 @@ public class NSLMainController implements Initializable {
@FXML
private TabPane mainTabPane;
@FXML
private Tab GamesTabHolder, RCMTabHolder, SMTabHolder;
private Tab GamesTabHolder, RCMTabHolder, SMTabHolder, PatchesTabHolder;
@FXML
private GamesController GamesTabController;
@ -55,6 +55,8 @@ public class NSLMainController implements Initializable {
private RcmController RcmTabController;
@FXML
private NxdtController NXDTabController;
@FXML
private PatchesController PatchesTabController;
@Override
public void initialize(URL url, ResourceBundle rb) {
@ -68,9 +70,13 @@ public class NSLMainController implements Initializable {
MediatorControl.getInstance().setController(this);
if (AppPreferences.getInstance().getAutoCheckUpdates()){
AppPreferences preferences = AppPreferences.getInstance();
if (preferences.getAutoCheckUpdates())
checkForUpdates();
}
if (preferences.getPatchesTabInvisible())
mainTabPane.getTabs().remove(3);
openLastOpenedTab();
}
@ -127,6 +133,8 @@ public class NSLMainController implements Initializable {
public RcmController getRcmCtrlr(){ return RcmTabController; }
public NxdtController getNXDTabController(){ return NXDTabController; }
public PatchesController getPatchesTabController(){ return PatchesTabController; }
/**
* Save preferences before exit
* */
@ -136,7 +144,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();
}
@ -152,6 +160,9 @@ public class NSLMainController implements Initializable {
case "SMTabHolder":
mainTabPane.getSelectionModel().select(SMTabHolder);
break;
case "PatchesTabHolder":
mainTabPane.getSelectionModel().select(PatchesTabHolder);
break;
}
}
private void saveLastOpenedTab(){

View File

@ -0,0 +1,351 @@
/*
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.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 {
@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;
statusLbl.setText("");
if (MediatorControl.getInstance().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;
statusLbl.setText("");
if (MediatorControl.getInstance().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;
statusLbl.setText("");
if (MediatorControl.getInstance().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();
}
public void notifyThreadStarted(boolean isActive, EModule type) {
if (! type.equals(EModule.PATCHES)) {
patchesToolPane.setDisable(isActive);
return;
}
convertRegionEs.getStyleClass().clear();
makeFsBtn.setVisible(! isActive);
makeLoaderBtn.setVisible(! isActive);
if (isActive) {
MediatorControl.getInstance().getContoller().logArea.clear();
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");
}
public void setOneLineStatus(boolean statusSuccess){
if (statusSuccess)
statusLbl.setText(resourceBundle.getString("done_txt"));
else
statusLbl.setText(resourceBundle.getString("failure_txt"));
}
void updatePreferencesOnExit(){
AppPreferences.getInstance().setPatchesSaveToLocation(saveToLbl.getText());
if (locationKeysLbl.getText().isEmpty())
return;
AppPreferences.getInstance().setKeysLocation(locationKeysLbl.getText());
}
}

View File

@ -43,6 +43,9 @@ import java.util.ResourceBundle;
public class SettingsBlockGenericController implements Initializable {
@FXML
private ChoiceBox<LocaleHolder> languagesChB;
@FXML
private Button fontSelectBtn;
@FXML
private Button submitLanguageBtn,
driversInstallBtn,
@ -81,6 +84,14 @@ public class SettingsBlockGenericController implements Initializable {
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(){

View File

@ -38,7 +38,7 @@ public class SettingsBlockGoldleafController implements Initializable {
final AppPreferences preferences = AppPreferences.getInstance();
nspFilesFilterForGLCB.setSelected(preferences.getNspFileFilterGL());
glVersionChoiceBox.getItems().addAll(AppPreferences.goldleafSupportedVersions);
glVersionChoiceBox.getItems().addAll(AppPreferences.GOLDLEAF_SUPPORTED_VERSIONS);
glVersionChoiceBox.getSelectionModel().select(preferences.getGlVersion());
}

View File

@ -55,7 +55,7 @@ public class SettingsBlockTinfoilController implements Initializable {
final AppPreferences preferences = AppPreferences.getInstance();
networkExpertSettingsVBox.disableProperty().bind(networkExpertModeCB.selectedProperty().not());
networkExpertSettingsVBox.visibleProperty().bind(networkExpertModeCB.selectedProperty());
pcIpTF.disableProperty().bind(autoDetectIpCB.selectedProperty());
pcPortTF.disableProperty().bind(randomlySelectPortCB.selectedProperty());

View File

@ -40,11 +40,12 @@ public class MediatorControl {
}
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 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 PatchesController getPatchesController(){ return mainController.getPatchesTabController(); }
public ResourceBundle getResourceBundle(){
return mainController.getResourceBundle();
@ -56,6 +57,11 @@ public class MediatorControl {
getSplitMergeController().notifyThreadStarted(isActive, appModuleType);
getRcmController().notifyThreadStarted(isActive, appModuleType);
getNxdtController().notifyThreadStarted(isActive, appModuleType);
getPatchesController().notifyThreadStarted(isActive, appModuleType);
}
public synchronized boolean getTransferActive() { return this.isTransferActive.get(); }
public void updateApplicationFont(String fontFamily, double fontSize){
mainController.logArea.getScene().getRoot().setStyle(
String.format("-fx-font-family: \"%s\"; -fx-font-size: %.0f;", fontFamily, fontSize));
}
}

View File

@ -112,6 +112,8 @@ public class MessagesConsumer extends AnimationTimer {
case SPLIT_MERGE_TOOL:
MediatorControl.getInstance().getSplitMergeController().setOneLineStatus(oneLinerStatus.get());
break;
case PATCHES:
MediatorControl.getInstance().getPatchesController().setOneLineStatus(oneLinerStatus.get());
}
this.stop();
}

View File

@ -22,5 +22,6 @@ public enum EModule {
USB_NET_TRANSFERS,
SPLIT_MERGE_TOOL,
RCM,
NXDT
NXDT,
PATCHES
}

View File

@ -28,11 +28,12 @@ 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 {
public static final String appVersion = "v5.1";
public static String appVersion;
public static boolean isCli;
@Override
@ -46,10 +47,10 @@ public class NSLMain extends Application {
Parent root = loader.load();
primaryStage.getIcons().addAll(
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"))
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")))
);
primaryStage.setTitle("NS-USBloader "+appVersion);
@ -61,13 +62,15 @@ 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.getInstance().getTransferActive())
if(! ServiceWindow.getConfirmationWindow(rb.getString("windowTitleConfirmExit"), rb.getString("windowBodyConfirmExit")))
if(! ServiceWindow.getConfirmationWindow(rb.getString("windowTitleConfirmExit"),
rb.getString("windowBodyConfirmExit")))
e.consume();
});
@ -81,6 +84,7 @@ public class NSLMain extends Application {
}
public static void main(String[] args) {
NSLMain.appVersion = ResourceBundle.getBundle("app").getString("_version");
if (args.length == 0) {
launch(args);
}

View File

@ -1,71 +0,0 @@
/*
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");
}
}

View File

@ -44,7 +44,6 @@ 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);
@ -54,6 +53,9 @@ 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();
}
@ -68,7 +70,6 @@ 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);
@ -78,6 +79,10 @@ 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();

View File

@ -1,5 +1,5 @@
/*
Copyright 2019-2020 Dmitry Isaenko
Copyright 2019-2022 Dmitry Isaenko
This file is part of NS-USBloader.
@ -26,16 +26,14 @@ 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 country = localeFileName.substring(7, 9);
String language = localeFileName.substring(10, 12);
this.locale = new Locale(country, language);
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);
this.localeCode = locale.toString();
this.languageName = locale.getDisplayLanguage(locale) + " (" + locale + ")";
}
@ -47,7 +45,7 @@ public class LocaleHolder {
public String getLocaleCode(){
return localeCode;
};
}
public Locale getLocale() {
return locale;

View File

@ -1,5 +1,5 @@
/*
Copyright 2019-2020 Dmitry Isaenko
Copyright 2019-2023 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() == driversFileSize;
return driversInstallerFile != null && driversInstallerFile.length() == DRIVERS_FILE_SIZE;
}
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, driversFileSize);
updateProgress(totalRead, DRIVERS_FILE_SIZE);
if (this.isCancelled()) {
bis.close();
fos.close();

View File

@ -1,5 +1,5 @@
/*
Copyright 2019-2020 Dmitry Isaenko
Copyright 2019-2023 Dmitry Isaenko
This file is part of NS-USBloader.
@ -32,19 +32,32 @@ import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import nsusbloader.AppPreferences;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.File;
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;
@ -52,11 +65,11 @@ public class DriversInstall {
DownloadDriversTask downloadTask = new DownloadDriversTask();
Button cancelButton = new Button(rb.getString("btn_Cancel"));
Button cancelButton = new Button(resourceBundle.getString("btn_Cancel"));
HBox hBoxInformation = new HBox();
hBoxInformation.setAlignment(Pos.TOP_LEFT);
hBoxInformation.getChildren().add(new Label(rb.getString("windowBodyDownloadDrivers")));
hBoxInformation.getChildren().add(new Label(resourceBundle.getString("windowBodyDownloadDrivers")));
ProgressBar progressBar = new ProgressBar();
progressBar.setPrefWidth(Double.MAX_VALUE);
@ -93,7 +106,7 @@ public class DriversInstall {
Stage stage = new Stage();
stage.setTitle(rb.getString("windowTitleDownloadDrivers"));
stage.setTitle(resourceBundle.getString("windowTitleDownloadDrivers"));
stage.getIcons().addAll(
new Image("/res/dwnload_ico32x32.png"), //TODO: REDRAW
new Image("/res/dwnload_ico48x48.png"),
@ -106,6 +119,7 @@ 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 );
@ -117,7 +131,7 @@ public class DriversInstall {
stage.toFront();
downloadTask.setOnSucceeded(event -> {
cancelButton.setText(rb.getString("btn_Close"));
cancelButton.setText(resourceBundle.getString("btn_Close"));
String returnedValue = downloadTask.getValue();
@ -143,7 +157,7 @@ public class DriversInstall {
return true;
}
catch (Exception e){
runInstallerStatusLabel.setText("Error: "+e.toString());
runInstallerStatusLabel.setText("Error: "+e);
e.printStackTrace();
return false;
}

View File

@ -0,0 +1,45 @@
/*
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);
}

View File

@ -0,0 +1,591 @@
/*
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();
}
}

View File

@ -0,0 +1,26 @@
/*
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);
}
}

View File

@ -0,0 +1,161 @@
/*
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;
}
}
}

View File

@ -0,0 +1,50 @@
/*
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;
}
}
}

View File

@ -0,0 +1,181 @@
/*
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);
}
}

View File

@ -0,0 +1,182 @@
/*
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;
}
}

View File

@ -0,0 +1,103 @@
/*
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);
}
}

View File

@ -0,0 +1,161 @@
/*
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);
}
}

View File

@ -0,0 +1,145 @@
/*
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();
}
}

View File

@ -0,0 +1,129 @@
/*
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; }
}

View File

@ -0,0 +1,163 @@
/*
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();
}
}
}

View File

@ -0,0 +1,50 @@
/*
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;
}
}

View File

@ -0,0 +1,218 @@
/*
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);
}
}

View File

@ -0,0 +1,185 @@
/*
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;
}
}

View File

@ -0,0 +1,90 @@
/*
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);
}
}

View File

@ -0,0 +1,97 @@
/*
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);
}
}

View File

@ -0,0 +1,115 @@
/*
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; }
}

View File

@ -0,0 +1,115 @@
/*
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();
}
}
}

View File

@ -0,0 +1,148 @@
/*
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);
}
}

View File

@ -0,0 +1,125 @@
/*
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;
}
}

View File

@ -32,7 +32,6 @@ public class CommandLineInterface {
}
final Options cliOptions = createCliOptions();
CommandLineParser cliParser = new DefaultParser();
try{
CommandLine cli = cliParser.parse(cliOptions, args);
@ -68,6 +67,11 @@ 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");
@ -154,6 +158,12 @@ 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")
@ -184,6 +194,7 @@ public class CommandLineInterface {
group.addOption(helpOption);
group.addOption(tinfoilOption);
group.addOption(glOption);
group.addOption(experimentalOption);
//group.addOption(nxdtOption);
group.addOption(splitOption);
group.addOption(mergeOption);

View File

@ -0,0 +1,46 @@
/*
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");
}
}

View File

@ -34,7 +34,7 @@ public class GoldLeafCli {
private int parseFileSince = 1;
public GoldLeafCli(String[] arguments) throws InterruptedException, IncorrectSetupException{
GoldLeafCli(String[] arguments) throws InterruptedException, IncorrectSetupException{
this.arguments = arguments;
checkArguments();
@ -43,7 +43,7 @@ public class GoldLeafCli {
runGoldLeafBackend();
}
public void checkArguments() throws IncorrectSetupException{
private 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.goldleafSupportedVersions){
for (String a : AppPreferences.GOLDLEAF_SUPPORTED_VERSIONS){
builder.append("\t");
builder.append(a);
builder.append("\n");
@ -83,7 +83,7 @@ public class GoldLeafCli {
return builder.toString();
}
public void parseGoldLeafVersion() throws IncorrectSetupException{
private 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.goldleafSupportedVersions){
for (String version : AppPreferences.GOLDLEAF_SUPPORTED_VERSIONS){
if (version.equals(goldLeafVersion))
return;
}
@ -107,7 +107,7 @@ public class GoldLeafCli {
getGlSupportedVersions());
}
public void parseFilesArguments() throws IncorrectSetupException{
private void parseFilesArguments() throws IncorrectSetupException{
filesList = new ArrayList<>();
File file;
@ -123,7 +123,7 @@ public class GoldLeafCli {
}
}
public void runGoldLeafBackend() throws InterruptedException {
private void runGoldLeafBackend() throws InterruptedException {
Runnable task = new UsbCommunications(filesList,
"GoldLeaf"+goldLeafVersion,
filterForNsp);

View File

@ -27,7 +27,7 @@ public class NxdtCli {
private final String[] arguments;
private String saveTo;
public NxdtCli(String[] arguments) throws InterruptedException, IncorrectSetupException{
NxdtCli(String[] arguments) throws InterruptedException, IncorrectSetupException{
this.arguments = arguments;
parseArgument();
runBackend();

View File

@ -29,7 +29,7 @@ public class TinfoilUsbCli {
private final String[] arguments;
private List<File> filesList;
public TinfoilUsbCli(String[] arguments) throws InterruptedException, IncorrectSetupException{
TinfoilUsbCli(String[] arguments) throws InterruptedException, IncorrectSetupException{
this.arguments = arguments;
checkArguments();
parseFilesArguments();

File diff suppressed because it is too large Load Diff

View File

@ -197,7 +197,7 @@ class TinFoil extends TransferModule {
ae.printStackTrace();
return true;
} catch (NullPointerException npe){
print("NullPointerException (in some moment application didn't find something. Something important.):" +
print("Application didn't find something important. Make sure you have enough space on medium!" +
"\n "+npe.getMessage(), EMsgType.FAIL);
npe.printStackTrace();
return true;

View File

@ -49,7 +49,7 @@ public class UsbCommunications extends CancellableRunnable {
@Override
public void run() {
print("\tStart", EMsgType.INFO);
print("\tStart");
UsbConnect usbConnect = UsbConnect.connectHomebrewMode(logPrinter);
@ -66,6 +66,9 @@ public class UsbCommunications extends CancellableRunnable {
case "TinFoil":
module = new TinFoil(handler, nspMap, this, logPrinter);
break;
case "GoldLeafv0.10+":
module = new GoldLeaf_010(handler, nspMap, this, logPrinter, nspFilterForGl);
break;
case "GoldLeafv0.8-0.9":
module = new GoldLeaf_08(handler, nspMap, this, logPrinter, nspFilterForGl);
break;
@ -87,12 +90,12 @@ public class UsbCommunications extends CancellableRunnable {
*/
private void close(EFileStatus status){
logPrinter.update(nspMap, status);
print("\tEnd", EMsgType.INFO);
print("\tEnd");
logPrinter.close();
}
private void print(String message, EMsgType type){
private void print(String message){
try {
logPrinter.print(message, type);
logPrinter.print(message, EMsgType.INFO);
}
catch (InterruptedException ie){
ie.printStackTrace();

View File

@ -0,0 +1 @@
_version=v${project.version}

View File

@ -0,0 +1,40 @@
<?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>

View File

@ -55,7 +55,7 @@
<Insets />
</HBox.margin>
</Button>
<Button fx:id="selectSplitNspBtn" contentDisplay="TOP" mnemonicParsing="false" prefHeight="60.0" text="%btn_OpenSplitFile">
<Button fx:id="selectSplitBtn" 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>

View File

@ -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/8.0.141" 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/18" 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,6 +47,14 @@ 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" />

View File

@ -12,21 +12,12 @@
<?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/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.NxdtController">
<VBox spacing="15.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.NxdtController">
<HBox alignment="CENTER">
<children>
<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>
<Label styleClass="nxdt" text="nx" />
<Label styleClass="bold-text" text="dumptool" />
</children>
</HBox>
<GridPane>

View File

@ -0,0 +1,125 @@
<?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>

View File

@ -14,18 +14,13 @@
<?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/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.RcmController">
<ScrollPane fitToWidth="true" xmlns="http://javafx.com/javafx/18" 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 text="%tabRcm_Lbl_FuseeGelee">
<font>
<Font name="System Bold" size="15.0" />
</font>
</Label>
<Label styleClass="bold-text" text="%tabRcm_Lbl_FuseeGelee" />
</children>
</HBox>
<GridPane>
@ -57,11 +52,7 @@
<Label fx:id="payloadFNameLbl1" />
</children>
</HBox>
<Label fx:id="payloadFPathLbl1" disable="true">
<font>
<Font name="System Italic" size="13.0" />
</font>
</Label>
<Label fx:id="payloadFPathLbl1" disable="true" styleClass="italic-text" />
</children>
</VBox>
<Button fx:id="selPldBtn1" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
@ -86,11 +77,7 @@
<Label fx:id="payloadFNameLbl2" />
</children>
</HBox>
<Label fx:id="payloadFPathLbl2" disable="true">
<font>
<Font name="System Italic" size="13.0" />
</font>
</Label>
<Label fx:id="payloadFPathLbl2" disable="true" styleClass="italic-text" />
</children>
</VBox>
<Button fx:id="selPldBtn2" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
@ -115,11 +102,7 @@
<Label fx:id="payloadFNameLbl3" />
</children>
</HBox>
<Label fx:id="payloadFPathLbl3" disable="true">
<font>
<Font name="System Italic" size="13.0" />
</font>
</Label>
<Label fx:id="payloadFPathLbl3" disable="true" styleClass="italic-text" />
</children>
</VBox>
<Button fx:id="selPldBtn3" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
@ -144,11 +127,7 @@
<Label fx:id="payloadFNameLbl4" />
</children>
</HBox>
<Label fx:id="payloadFPathLbl4" disable="true">
<font>
<Font name="System Italic" size="13.0" />
</font>
</Label>
<Label fx:id="payloadFPathLbl4" disable="true" styleClass="italic-text" />
</children>
</VBox>
<Button fx:id="selPldBtn4" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">
@ -173,11 +152,7 @@
<Label fx:id="payloadFNameLbl5" />
</children>
</HBox>
<Label fx:id="payloadFPathLbl5" disable="true">
<font>
<Font name="System Italic" size="13.0" />
</font>
</Label>
<Label fx:id="payloadFPathLbl5" disable="true" styleClass="italic-text" />
</children>
</VBox>
<Button fx:id="selPldBtn5" mnemonicParsing="false" onAction="#bntSelectPayloader" styleClass="buttonSelect">

View File

@ -10,7 +10,7 @@
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<VBox spacing="5.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="nsusbloader.Controllers.SettingsBlockGenericController">
<VBox spacing="5.0" xmlns="http://javafx.com/javafx/18" 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,6 +28,11 @@
<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>

View File

@ -12,19 +12,14 @@
<?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/8.0.141" 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/18" 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 text="%tabSplMrg_Lbl_SplitNMergeTitle">
<font>
<Font name="System Bold" size="15.0" />
</font>
</Label>
<Label styleClass="bold-text" text="%tabSplMrg_Lbl_SplitNMergeTitle" />
</children>
</HBox>
<GridPane>

View File

@ -11,8 +11,9 @@ windowBodyConfirmExit=Data transfer is in progress and closing this application
windowTitleConfirmExit=No, don't do this!
btn_Stop=Interrupt
tab3_Txt_GreetingsMessage2=--\n\
Source: https://github.com/developersu/ns-usbloader/\n\
Site: https://developersu.blogspot.com/search/label/NS-USBloader\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
@ -44,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 NSP
btn_OpenSplitFile=Select split
tab2_Lbl_ApplicationSettings=Main settings
tabSplMrg_Lbl_SplitNMergeTitle=Split & merge files tool
tabSplMrg_RadioBtn_Split=Split
@ -77,4 +78,20 @@ windowTitleAddingFiles=Searching for files...
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
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:

View File

@ -9,8 +9,9 @@ windowBodyConfirmExit=\u062C\u0627\u0631\u064A \u0646\u0642\u0644 \u0627\u0644\u
windowTitleConfirmExit=\u0644\u0627 , \u0644\u0627 \u062A\u0641\u0639\u0644 \u0630\u0644\u0643!
btn_Stop=\u0625\u064A\u0642\u0627\u0641
tab3_Txt_GreetingsMessage2=--\n\
\u0627\u0644\u0645\u0635\u062F\u0631: https://github.com/developersu/ns-usbloader/\n\
\u0627\u0644\u0645\u0648\u0642\u0639: https://developersu.blogspot.com/search/label/NS-USBloader\n\
\u0627\u0644\u0645\u0635\u062F\u0631: https://git.redrise.ru/desu/ns-usbloader/\n\
Mirror: https://github.com/developersu/ns-usbloader/\n\
\u0627\u0644\u0645\u0648\u0642\u0639: https://redrise.ru\n\
Dmitry Isaenko [developer.su]
tab1_table_Lbl_Status=\u0627\u0644\u062D\u0627\u0644\u0629
tab1_table_Lbl_FileName=\u0627\u0633\u0645 \u0627\u0644\u0645\u0644\u0641
@ -42,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 "\u0625\u0646 \u0625\u0633 \u0628\u064A"
btn_OpenSplitFile=\u0627\u062E\u062A\u0631 \u062A\u0642\u0633\u064A\u0645 \u0645\u0644\u0641 \u0627\u0644
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
@ -70,3 +71,4 @@ tab2_Cb_GlVersion=\u0625\u0635\u062F\u0627\u0631 \u0628\u0631\u0646\u0627\u0645\
tab2_Cb_GLshowNspOnly=\u0627\u0639\u0631\u0636 \u0641\u0642\u0637 \u0627\u0644\u0645\u0644\u0641\u0627\u062A \u0630\u0627\u062A \u0627\u0644\u0625\u0645\u062A\u062F\u0627\u062F "\u0625\u0646 \u0625\u0633 \u0628\u064A" \u0641\u064A \u0628\u0631\u0646\u0627\u0645\u062C \u0627\u0644\u0640 "\u062C\u0648\u0644\u062F \u0644\u064A\u0641".
windowBodyPleaseStopOtherProcessFirst=\u0645\u0646 \u0641\u0636\u0644\u0643 \u0642\u0645 \u0628\u0625\u064A\u0642\u0627\u0641 \u0627\u0644\u0639\u0645\u0644\u064A\u0627\u062A \u0627\u0644\u0623\u062E\u0631\u0649 \u0642\u0628\u0644 \u0627\u0644\u0625\u0633\u062A\u0645\u0631\u0627\u0631.

View File

@ -9,8 +9,9 @@ windowBodyConfirmExit=Pr\u00E1v\u011B prob\u00EDh\u00E1 p\u0159enos dat a zav\u0
windowTitleConfirmExit=Ne, te\u010F nechci odej\u00EDt!
btn_Stop=P\u0159eru\u0161it
tab3_Txt_GreetingsMessage2=--\n\
Source: https://github.com/developersu/ns-usbloader/\n\
Site: https://developersu.blogspot.com/search/label/NS-USBloader\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=Stav
tab1_table_Lbl_FileName=N\u00E1zev souboru
@ -42,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 NSP
btn_OpenSplitFile=Zvolit rozd\u011Blen\u00E9 soubor
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
@ -70,3 +71,4 @@ tab2_Cb_GlVersion=GoldLeaf verze
tab2_Cb_GLshowNspOnly=Uk\u00E1zat v GoldLeafu pouze *.nsp.
windowBodyPleaseStopOtherProcessFirst=Pros\u00EDm, p\u0159ed pokra\u010Dov\u00E1n\u00EDm nejprve zru\u0161te aktivn\u00ED p\u0159enos.

View File

@ -11,8 +11,9 @@ windowBodyConfirmExit=Der Datentransfer ist noch nicht abgeschlossen; das Schlie
windowTitleConfirmExit=Nein, mach das nicht!
btn_Stop=Unterbrechen
tab3_Txt_GreetingsMessage2=--\n\
Source: https://github.com/developersu/ns-usbloader/\n\
Site: https://developersu.blogspot.com/search/label/NS-USBloader\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=Dateiname
@ -44,8 +45,9 @@ 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-NSP ausw\uFFFDhlen
btn_OpenSplitFile=Split-file ausw\uFFFDhlen
tab2_Cb_GLshowNspOnly=Nur *.nsp in GoldLeaf zeigen.
btn_Cancel=Abbrechen

View File

@ -1,79 +0,0 @@
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://github.com/developersu/ns-usbloader/\n\
Site: https://developersu.blogspot.com/search/label/NS-USBloader\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:

View File

@ -1,47 +1,81 @@
btn_OpenFile=Seleccionar los archivos
btn_OpenFile=Seleccionar archivos
btn_OpenFolders=Seleccionar carpeta
btn_Upload=Enviar a NS
tab3_Txt_EnteredAsMsg1=Est\u00E1 conectado como:
tab3_Txt_EnteredAsMsg2=Deber\u00EDa ser root o haber configurado las reglas 'udev' de este usuario para evitar problemas.
tab3_Txt_FilesToUploadTitle=Archivos a subir:
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=Est\u00E1s conectado como:
tab3_Txt_EnteredAsMsg2=Debes tener permisos root o haber configurado las reglas 'udev' de este usuario para evitar problemas.
tab3_Txt_FilesToUploadTitle=Archivos a enviar:
tab3_Txt_GreetingsMessage=Bienvenido a NS-USBloader
tab3_Txt_NoFolderOrFileSelected=No ha seleccionado ning\u00FAn archivo: Nada se subir\u00E1.
windowBodyConfirmExit=Transferencia de datos en progreso, cerrar la aplicaci\u00F3n lo interrumpir\u00E1.\nNo se recomienda.\nInterrumpir proceso y salir?
windowTitleConfirmExit=No, no haga esto!
tab3_Txt_NoFolderOrFileSelected=Ning\u00FAn archivo seleccionado: No se enviar\u00E1 nada.
windowBodyConfirmExit=Se est\u00E1n transfiriendo archivos y cerrar la aplicaci\u00F3n lo interrumpir\u00E1.\nNo debes hacer esto.\n\u00BFInterrumpir el proceso y salir?
windowTitleConfirmExit=\u00A1No hagas esto!
btn_Stop=Interrumpir
tab3_Txt_GreetingsMessage2=--\n\
Source: https://github.com/developersu/ns-usbloader/\n\
Site: https://developersu.blogspot.com/search/label/NS-USBloader\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=Estado
tab1_table_Lbl_Status=Estatus
tab1_table_Lbl_FileName=Nombre del archivo
tab1_table_Lbl_Size=Tama\u00F1o
tab1_table_Lbl_Upload=Enviar?
tab1_table_contextMenu_Btn_BtnDelete=Eliminar
tab1_table_contextMenu_Btn_DeleteAll=Eliminar todo
tab1_table_Lbl_Upload=\u00BFEnviar?
tab1_table_contextMenu_Btn_BtnDelete=Quitar
tab1_table_contextMenu_Btn_DeleteAll=Quitar todos
tab2_Lbl_HostIP=IP del host
tab1_Lbl_NSIP=NS IP:
tab2_Cb_ValidateNSHostName=Validar siempre la entrada de IP de la NS.
windowBodyBadIp=Est\u00E1 seguro de que ha introducido la IP de la NS correctamente?
windowTitleBadIp=Es posible que la direcci\u00F3n IP de la NS sea incorrecta
tab2_Cb_ExpertMode=Modo Experto
tab2_Lbl_HostPort=Puerto
tab2_Cb_AutoDetectIp=Detectar IP autom\u00E1ticamente
tab2_Cb_RandSelectPort=Obtener el puerto autom\u00E1ticamente
tab2_Cb_DontServeRequests=No contestar solicitudes
tab2_Lbl_DontServeRequestsDesc=Si habilita esta opci\u00F3n, el ordenador no responder\u00E1 solicitudes de archivos NSP de la NS (en la red), y usar\u00E1 las configuraciones definidas por el host para indicar a Awoo donde se encuentran los archivos
tab2_Lbl_HostExtra=Extra
windowTitleErrorPort=Puerto asignado incorrectamente!
windowBodyErrorPort=El puerto no puede ser 0 o mayor que 65535
tab2_Cb_AutoCheckForUpdates=Comprobar actualizaciones autom\u00E1ticamente
windowTitleNewVersionAval=Actualizaci\u00F3n disponible
windowTitleNewVersionNOTAval=No hay actualizaciones disponibles
windowTitleNewVersionUnknown=No fue posible encontrar actualizaciones
windowBodyNewVersionUnknown=Algo fall\u00F3\nLa conexi\u00F3n a internet no funciona correctamente, o GitHub est\u00E1 ca\u00EDdo
tab1_Lbl_NSIP=IP del NS:
tab2_Cb_ValidateNSHostName=Siempre verifica el IP del NS.
windowBodyBadIp=\u00BFEst\u00E1s seguro que la direcci\u00F3n IP ingresada es la del NS?
windowTitleBadIp=La IP del NS parece ser incorrecta.
tab2_Cb_ExpertMode=Modo experto (NET setup)
tab2_Lbl_HostPort=puerto
tab2_Cb_AutoDetectIp=Detectar autom\u00E1ticamente la IP
tab2_Cb_RandSelectPort=Obtener puerto aleatoriamente
tab2_Cb_DontServeRequests=No responder solicitudes
tab2_Lbl_DontServeRequestsDesc=Si se activa, esta computadora no responder\u00E1 a las solicitudes de archivos NSP provenientes del NS (en la red) y se usar\u00E1n las configuraciones definidas por el host para decirle a Awoo Installer (o aplicaciones compatibles) donde buscar por los archivos.
tab2_Lbl_HostExtra=extra
windowTitleErrorPort=\u00A1Puerto incorrecto!
windowBodyErrorPort=\u00A1Puerto incorrecto!
tab2_Cb_AutoCheckForUpdates=Buscar actualizaciones autom\u00E1ticamente
windowTitleNewVersionAval=Nueva versi\u00F3n disponible
windowTitleNewVersionNOTAval=No hay ninguna nueva versi\u00F3n disponible
windowTitleNewVersionUnknown=No se pueden buscar actualizaciones
windowBodyNewVersionUnknown=Algo sali\u00F3 mal\nQuiz\u00E1s no tienes conexi\u00F3n a internet, o GitHub est\u00E1 caido
windowBodyNewVersionNOTAval=Est\u00E1s usando la \u00FAltima versi\u00F3n
tab2_Cb_AllowXciNszXcz=Permite la selecci\u00F3n de archivos XCI / NSZ / XCZ para Awoo
tab2_Lbl_AllowXciNszXczDesc=Usado por algunas aplicaciones de terceros que soportan XCI/NSZ/XCZ y que utilizan el protocolo de transferencia de Tinfoil. Si no est\u00E1 seguro no cambie la opci\u00F3n.
tab2_Cb_AllowXciNszXcz=Permitir seleccionar archivos XCI / NSZ / XCZ en Awoo
tab2_Lbl_AllowXciNszXczDesc=Usado por aplicaciones que soportan XCI/NSZ/XCZ y utilizan el protocolo de transferencia Awoo (Adubbz/TinFoil). No modificar si no est\u00E1s seguro. Habilitar para Awoo Installer.
tab2_Lbl_Language=Idioma
windowBodyRestartToApplyLang=Por favor, reinicie el programa para aplicar los cambios.
tab2_Cb_GLshowNspOnly=Mostrar solo *.nsp en GoldLeaf.
windowBodyRestartToApplyLang=Reinicia la aplicaci\u00F3n para aplicar los cambios.
btn_OpenSplitFile=Seleccionar NSP en partes
tab2_Lbl_ApplicationSettings=Ajustes principales
tabSplMrg_Lbl_SplitNMergeTitle=Herramienta para dividir y fusionar archivos
tabSplMrg_RadioBtn_Split=Dividir
tabSplMrg_RadioBtn_Merge=Fusionar
tabSplMrg_Txt_File=Archivo:
tabSplMrg_Txt_Folder=Archivo dividido (carpeta):
tabSplMrg_Btn_SelectFile=Seleccionar archivo
tabSplMrg_Btn_SelectFolder=Seleccionar carpeta
tabSplMrg_Lbl_SaveToLocation=Guardar en:
tabSplMrg_Btn_ChangeSaveToLocation=Cambiar
tabSplMrg_Btn_Convert=Convertir
windowTitleError=Error
windowBodyPleaseFinishTransfersFirst=No se pueden dividir/fusionar archivos mientras se est\u00E1 realizando otro proceso. Por favor, cancela las operaciones de transferencia activas primero.
done_txt=\u00A1Listo!
failure_txt=Error
btn_Select=Seleccionar
btn_InjectPayloader=Injectar payload
tabNXDT_Btn_Start=\u00A1Iniciar!
tab2_Btn_InstallDrivers=Descargar e instalar controladores
windowTitleDownloadDrivers=Descargar e instalar controladores
windowBodyDownloadDrivers=Descargando controladores (libusbK v3.0.7.0)...
btn_Cancel=Cancelar
btn_Close=Cerrar
tab2_Cb_GlVersion=Versi\u00F3n de GoldLeaf
tab2_Cb_GLshowNspOnly=Mostrar solo *.nsp en GoldLeaf.
windowBodyPleaseStopOtherProcessFirst=Det\u00E9n los dem\u00E1s procesos activos antes de continuar.
tab2_Cb_foldersSelectorForRoms=Seleccionar una carpeta con archivos ROM en lugar de seleccionarlos individualmente.
tab2_Cb_foldersSelectorForRomsDesc=Cambia el comportamiento del bot\u00F3n de 'Seleccionar archivos' en la pesta\u00F1a 'Juegos': en lugar de seleccionar archivos ROM uno por uno puedes seleccionar una carpeta para instalarlos todos a la vez.
windowTitleAddingFiles=Buscando archivos...
windowBodyFilesScanned=Archivos encontrados: %d\nSe a\u00F1adir\u00E1n: %d
tab2_Lbl_AwooBlockTitle=Awoo Installer y compatibles
tabRcm_Lbl_Payload=Payload:
tabRcm_Lbl_FuseeGelee=Fus\u00E9e Gel\u00E9e RCM

View File

@ -1,6 +1,8 @@
btn_OpenFile=Selectionner les fichiers
btn_OpenFile=S\u00E9l\u00E9ctionner les fichiers
btn_OpenFolders=S\u00E9l\u00E9ctionner un dossier
btn_Upload=Envoyer vers NS
tab3_Txt_EnteredAsMsg1=Vous etes connect\u00E9 en tant que:
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_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
@ -9,20 +11,21 @@ windowBodyConfirmExit=Le transfert de donn\u00E9es est en cours et la fermeture
windowTitleConfirmExit=Non, ne faites pas \u00E7a!
btn_Stop=Interrompre
tab3_Txt_GreetingsMessage2=--\n\
Source: https://github.com/developersu/ns-usbloader/\n\
Site: https://developersu.blogspot.com/search/label/NS-USBloader\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_Upload=Envoyer ?
tab1_table_Lbl_Size=Taille
tab1_table_Lbl_FileName=Nom de fichier
tab1_table_Lbl_Status=Statut
tab1_table_Lbl_FileName=Nom de fichier
tab1_table_Lbl_Size=Taille
tab1_table_Lbl_Upload=Envoyer ?
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
windowTitleBadIp=L'adresse IP de NS est probablement incorrecte
windowBodyBadIp=\u00CAtes-vous s\u00FBr que l'adresse IP de NS entr\u00E9e est correcte ?
windowTitleBadIp=L'adresse IP de NS est probablement incorrecte
tab2_Cb_ExpertMode=Mode expert
tab2_Lbl_HostPort=port
tab2_Cb_AutoDetectIp=D\u00E9tection automatique d'IP
@ -36,11 +39,24 @@ 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
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
windowBodyNewVersionNOTAval=Vous utilisez la derni\u00E8re version
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=La langue
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
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.

View File

@ -11,8 +11,9 @@ windowBodyConfirmExit=Il trasferimento dei dati \u00E8 in corso e la chiusura de
windowTitleConfirmExit=No, non farlo!
btn_Stop=Interrompi
tab3_Txt_GreetingsMessage2=--\n\
Sorgenti: https://github.com/developersu/ns-usbloader/\n\
Sito: https://developersu.blogspot.com/search/label/NS-USBloader\n\
Sorgenti: https://git.redrise.ru/desu/ns-usbloader\n\
Mirror: https://github.com/developersu/ns-usbloader/\n\
Sito: https://redrise.ru\n\
Dmitry Isaenko [developer.su]
tab1_table_Lbl_Status=Stato
tab1_table_Lbl_FileName=Nome file
@ -44,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 NSP troncato
btn_OpenSplitFile=Seleziona il file truncato
tab2_Lbl_ApplicationSettings=Impostazioni principali
tabSplMrg_Lbl_SplitNMergeTitle=Strumento tronca e unisci file
tabSplMrg_RadioBtn_Split=Tronca
@ -78,3 +79,4 @@ windowBodyFilesScanned=File scansionati: %d\nVerranno aggiunti: %d
tab2_Lbl_AwooBlockTitle=Awoo Installer e compatibili
tabRcm_Lbl_Payload=Payload:
tabRcm_Lbl_FuseeGelee=Fus\u00E9e Gel\u00E9e RCM

View File

@ -0,0 +1,82 @@
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

View File

@ -0,0 +1,81 @@
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

View File

@ -1,22 +1,24 @@
btn_OpenFile=\uD30C\uC77C \uC120\uD0DD
btn_OpenFolders=\uD30C\uC77C \uC120\uD0DD
btn_OpenFolders=\uD30C\uC77C \uC120\uD0DD
btn_Upload=NS\uC5D0 \uC5C5\uB85C\uB4DC
btn_OpenFolders_tooltip=\uC2A4\uCE94\uD560 \uD3F4\uB354\uB97C \uC120\uD0DD\uD569\uB2C8\uB2E4.\n\uC774 \uD3F4\uB354\uC640 \uBAA8\uB4E0 \uD558\uC704 \uD3F4\uB354\uAC00 \uAC80\uC0C9\uB429\uB2C8\uB2E4.\n\uC77C\uCE58\uD558\uB294 \uBAA8\uB4E0 \uD30C\uC77C\uC774 \uBAA9\uB85D\uC5D0 \uCD94\uAC00\uB429\uB2C8\uB2E4.
tab3_Txt_EnteredAsMsg1=\uB2E4\uC74C\uACFC \uAC19\uC774 \uC785\uB825\uB418\uC5C8\uC2B5\uB2C8\uB2E4:
tab3_Txt_EnteredAsMsg2=\uBB38\uC81C\uB97C \uBC29\uC9C0\uD558\uB824\uBA74 \uC774 \uC0AC\uC6A9\uC790\uC5D0 \uB300\uD574 \uB8E8\uD2B8\uC774\uAC70\uB098 'udev'\uADDC\uCE59\uC744 \uAD6C\uC131\uD574\uC57C \uD569\uB2C8\uB2E4.
tab3_Txt_FilesToUploadTitle=\uC5C5\uB85C\uB4DC \uD560 \uD30C\uC77C:
tab3_Txt_GreetingsMessage=NS-USBloader\uC5D0 \uC624\uC2E0 \uAC83\uC744 \uD658\uC601\uD569\uB2C8\uB2E4
tab3_Txt_GreetingsMessage=NS-USB\uB85C\uB354\uC5D0 \uC624\uC2E0 \uAC83\uC744 \uD658\uC601\uD569\uB2C8\uB2E4.
tab3_Txt_NoFolderOrFileSelected=\uC120\uD0DD\uD55C \uD30C\uC77C \uC5C6\uC74C: \uC5C5\uB85C\uB4DC \uD560 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.
windowBodyConfirmExit=\uB370\uC774\uD130 \uC804\uC1A1\uC774 \uC9C4\uD589 \uC911\uC774\uBA70 \uC774 \uC751\uC6A9 \uD504\uB85C\uADF8\uB7A8\uC744 \uB2EB\uC73C\uBA74 \uC911\uB2E8\uB429\uB2C8\uB2E4.\n\uC9C0\uAE08 \uD560 \uC218 \uC788\uB294 \uAC83\uC740 \uB354 \uB098\uC05C \uC77C\uC785\uB2C8\uB2E4.\n\uD504\uB85C\uC138\uC2A4\uB97C \uC911\uB2E8\uD558\uACE0 \uC885\uB8CC\uD558\uACA0\uC2B5\uB2C8\uAE4C?
windowTitleConfirmExit=\uC544\uB2C8\uC624, \uC774\uAC83\uC740 \uD558\uC9C0\uB9C8\uC138\uC694!
btn_Stop=\uC911\uB2E8
tab3_Txt_GreetingsMessage2=--\n\
Source: https://github.com/developersu/ns-usbloader/\n\
Site: https://developersu.blogspot.com/search/label/NS-USBloader\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=\uC0C1\uD0DC
tab1_table_Lbl_FileName=\uD30C\uC77C \uC774\uB984
tab1_table_Lbl_Size=\uD06C\uAE30
tab1_table_Lbl_Upload=\uC5C5\uB85C\uB4DC\uD569\uB2C8\uAE4C?
tab1_table_Lbl_Upload=\uC5C5\uB85C\uB4DC?
tab1_table_contextMenu_Btn_BtnDelete=\uC0AD\uC81C
tab1_table_contextMenu_Btn_DeleteAll=\uBAA8\uB450 \uC0AD\uC81C
tab2_Lbl_HostIP=\uD638\uC2A4\uD2B8 IP
@ -43,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 NSP \uC120\uD0DD
btn_OpenSplitFile=\uBD84\uD560 ROM \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
@ -74,3 +76,18 @@ tab2_Cb_foldersSelectorForRoms=ROM\uC744 \uAC1C\uBCC4\uC801\uC73C\uB85C \uC120\u
tab2_Cb_foldersSelectorForRomsDesc='\uAC8C\uC784' \uD0ED\uC5D0\uC11C '\uD30C\uC77C \uC120\uD0DD' \uBC84\uD2BC \uB3D9\uC791 \uBCC0\uACBD: ROM \uD30C\uC77C\uC744 \uD558\uB098\uC529 \uC120\uD0DD\uD558\uB294 \uB300\uC2E0 \uD3F4\uB354\uB97C \uC120\uD0DD\uD558\uC5EC \uC9C0\uC6D0\uB418\uB294 \uBAA8\uB4E0 \uD30C\uC77C\uC744 \uD55C \uBC88\uC5D0 \uCD94\uAC00 \uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.
windowTitleAddingFiles=\uD30C\uC77C \uAC80\uC0C9 \uC911...
windowBodyFilesScanned=\uC2A4\uCE94 \uB41C \uD30C\uC77C: %d\n\uCD94\uAC00 \uB420 \uAC83: %d
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.

View File

@ -9,8 +9,9 @@ windowBodyConfirmExit=Transfer\u00EAncia de dados em progresso: Fechar ir\u00E1
windowTitleConfirmExit=N\u00E3o, n\u00E3o fa\u00E7a isso!
btn_Stop=Interromper!
tab3_Txt_GreetingsMessage2=--\n\
Fonte: https://github.com/developersu/ns-usbloader/\n\
Site: https://developersu.blogspot.com/search/label/NS-USBloader\n\
Fonte: 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=Nome do Arquivo
@ -42,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 NSP
btn_OpenSplitFile=Select split file
tab2_Lbl_ApplicationSettings=Configura\u00E7\u00F5es principais
tabSplMrg_Lbl_SplitNMergeTitle=Ferramenta de Fragmentar (Split) & Mesclar (Merge) arquivos
tabSplMrg_RadioBtn_Split=Fragmentar (Dividir)
@ -69,3 +70,4 @@ btn_Close=Fechar
tab2_Cb_GlVersion=Vers\u00E3o do GoldLeaf
tab2_Cb_GLshowNspOnly=Mostrar apenas *.nsp no GoldLeaf.
windowBodyPleaseStopOtherProcessFirst=Por favor, pare outros processos ativos antes de prosseguir

View File

@ -11,8 +11,9 @@ windowBodyConfirmExit=Transferul de date este \u00EEn desf\u0103\u0219urare \u02
windowTitleConfirmExit=Nu, nu face asta!
btn_Stop=\u00CEntrerupere
tab3_Txt_GreetingsMessage2=--\n\
Source: https://github.com/developersu/ns-usbloader/\n\
Site: https://developersu.blogspot.com/search/label/NS-USBloader\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=Numele fi\u0219ierului
@ -44,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 NSP frac\u021Bionat
btn_OpenSplitFile=Selecteaz\u0103 pentru ROM 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
@ -74,4 +75,4 @@ windowBodyPleaseStopOtherProcessFirst=Te rog opre\u0219te toate cel\u0103lalte p
tab2_Cb_foldersSelectorForRoms=Selecteaz\u0103 directorul cu fi\u0219iere ROM \u00EEn loc s\u0103 selectezi fi\u0219iere ROM individual.
tab2_Cb_foldersSelectorForRomsDesc=Face ca 'Selecteaz\u0103 fi\u0219ierele' \u00EEn tab-ul 'Games' s\u0103 selecteze toate fi\u0219ierele de-o dat\u0103\u00A0\u00EEn loc de a selecta fi\u0219iere ROM unul c\u00E2te unul.
windowTitleAddingFiles=Caut fi\u0219iere...
windowBodyFilesScanned=Fi\u0219iere scanate: %d\nVor fi ad\u0103ugate: %d
windowBodyFilesScanned=Fi\u0219iere scanate: %d\nVor fi ad\u0103ugate: %d

View File

@ -9,8 +9,9 @@ windowBodyConfirmExit=\u0421\u0435\u0439\u0447\u0430\u0441 \u043F\u0440\u043E\u0
windowTitleConfirmExit=\u041D\u0435\u0442, \u043E\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0441\u044C!
btn_Stop=\u041F\u0440\u0435\u0440\u0432\u0430\u0442\u044C
tab3_Txt_GreetingsMessage2=--\n\
\u0418\u0441\u0445\u043E\u0434\u043D\u044B\u0439 \u043A\u043E\u0434: https://github.com/developersu/ns-usbloader/\n\
\u0421\u0430\u0439\u0442: https://developersu.blogspot.com/search/label/NS-USBloader\n\
\u0418\u0441\u0445\u043E\u0434\u043D\u044B\u0439 \u043A\u043E\u0434: https://git.redrise.ru/desu/ns-usbloader\n\
\u0417\u0435\u0440\u043A\u0430\u043B\u043E: https://github.com/developersu/ns-usbloader/\n\
\u0421\u0430\u0439\u0442: https://redrise.ru\n\
\u0418\u0441\u0430\u0435\u043D\u043A\u043E \u0414\u043C\u0438\u0442\u0440\u0438\u0439 [developer.su]
tab1_table_Lbl_Upload=\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044C?
tab1_table_Lbl_Size=\u0420\u0430\u0437\u043C\u0435\u0440
@ -22,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
@ -43,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 NSP
btn_OpenSplitFile=\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0440\u0430\u0437\u0431\u0438\u0442\u044B\u0439 \u0444\u0430\u0439\u043B
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
@ -76,4 +77,21 @@ 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:

View File

@ -0,0 +1,81 @@
btn_OpenFile=V\u00E4lj filer
btn_OpenFolders=V\u00E4lj mapp
btn_Upload=Skicka upp till NS
btn_OpenFolders_tooltip=V\u00E4lj en mapp att skanna.\nDenna mapp och alla dess undermappar kommer att skannas.\nAlla matchande filer kommer att l\u00E4ggas till i listan.
tab3_Txt_EnteredAsMsg1=Du har startat som:
tab3_Txt_EnteredAsMsg2=Du b\u00F6r vara root eller ha konfigurerat 'udev'-regler f\u00F6r denna anv\u00E4ndare f\u00F6r att undvika problem.
tab3_Txt_FilesToUploadTitle=Filer att skicka upp:
tab3_Txt_GreetingsMessage=V\u00E4lkommen till NS-USBloader
tab3_Txt_NoFolderOrFileSelected=Inga filer markerade: ingenting att skicka upp.
windowBodyConfirmExit=Data\u00F6verf\u00F6ring p\u00E5g\u00E5r och st\u00E4nger du detta program kommer den avbrytas.\nDet \u00E4r det v\u00E4rsta du kan g\u00F6ra nu.\nAvbryta processen och avsluta?
windowTitleConfirmExit=Nej, g\u00F6r inte detta!
btn_Stop=Avbryt
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=Filnamn
tab1_table_Lbl_Size=Storlek
tab1_table_Lbl_Upload=Skicka upp?
tab1_table_contextMenu_Btn_BtnDelete=Ta bort
tab1_table_contextMenu_Btn_DeleteAll=Ta bort alla
tab2_Lbl_HostIP=V\u00E4rdens IP
tab1_Lbl_NSIP=NS IP:
tab2_Cb_ValidateNSHostName=Validera alltid NS IP-inmatning.
windowBodyBadIp=\u00C4r du s\u00E4ker p\u00E5 att du har angivet NS IP-adress korrekt?
windowTitleBadIp=IP-adress f\u00F6r NS \u00E4r antagligen felaktig
tab2_Cb_ExpertMode=Expertl\u00E4ge (NET setup)
tab2_Lbl_HostPort=port
tab2_Cb_AutoDetectIp=Autodetektera IP
tab2_Cb_RandSelectPort=Slumpm\u00E4ssig port
tab2_Cb_DontServeRequests=Hantera inte beg\u00E4ran
tab2_Lbl_DontServeRequestsDesc=Om vald, kommer denna dator inte att svara p\u00E5 beg\u00E4ran av NSP-filer som kommer fr\u00E5n NS (\u00F6ver n\u00E4tet) och anv\u00E4nder definierade v\u00E4rdinst\u00E4llningar f\u00F6r att instruera Awoo Installer (eller kompatibla program) var den ska leta efter filer.
tab2_Lbl_HostExtra=extra
windowTitleErrorPort=Port inst\u00E4lld felaktigt!
windowBodyErrorPort=Port kan inte vara 0 eller h\u00F6gre \u00E4n 65535.
tab2_Cb_AutoCheckForUpdates=Automatisk uppdateringskontroll
windowTitleNewVersionAval=Ny version tillg\u00E4nglig
windowTitleNewVersionNOTAval=Inga nya versioner tillg\u00E4ngliga
windowTitleNewVersionUnknown=Kunde inte leta efter nya versioner
windowBodyNewVersionUnknown=N\u00E5gonting gick fel\nKanske inte kan n\u00E5 internet, eller GitHub \u00E4r nere
windowBodyNewVersionNOTAval=Du anv\u00E4nder den senaste versionen
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
tab2_Lbl_ApplicationSettings=Huvudinst\u00E4llningar
tabSplMrg_Lbl_SplitNMergeTitle=Verktyg f\u00F6r att dela upp och sl\u00E5 ihop filer
tabSplMrg_RadioBtn_Split=Dela upp
tabSplMrg_RadioBtn_Merge=Sl\u00E5 ihop
tabSplMrg_Txt_File=Fil:
tabSplMrg_Txt_Folder=Dela upp fil (mapp):
tabSplMrg_Btn_SelectFile=V\u00E4lj fil
tabSplMrg_Btn_SelectFolder=V\u00E4lj mapp
tabSplMrg_Lbl_SaveToLocation=Spara till:
tabSplMrg_Btn_ChangeSaveToLocation=\u00C4ndra
tabSplMrg_Btn_Convert=Konvertera
windowTitleError=Fel
windowBodyPleaseFinishTransfersFirst=Kunde inte dela upp/sl\u00E5 ihop filer n\u00E4r programmets USB/n\u00E4tverksprocess \u00E4r aktiv. Avbryt f\u00F6rst aktiva \u00F6verf\u00F6ringar.
done_txt=F\u00E4rdig!
failure_txt=Misslyckades
btn_Select=V\u00E4lj
btn_InjectPayloader=Injicera payload
tabNXDT_Btn_Start=Starta!
tab2_Btn_InstallDrivers=H\u00E4mta och installera drivrutiner
windowTitleDownloadDrivers=H\u00E4mta och installera drivrutiner
windowBodyDownloadDrivers=H\u00E4mtar drivrutiner (libusbK v3.0.7.0)...
btn_Cancel=Avbryt
btn_Close=St\u00E4ng
tab2_Cb_GlVersion=GoldLeaf version
tab2_Cb_GLshowNspOnly=Visa endast *.nsp i GoldLeaf.
windowBodyPleaseStopOtherProcessFirst=Stoppa andra aktiva processer innan du forts\u00E4tter.
tab2_Cb_foldersSelectorForRoms=V\u00E4lj mapp med ROM-filer ist\u00E4llet f\u00F6r att v\u00E4lja enstaka ROM-filer.
tab2_Cb_foldersSelectorForRomsDesc=\u00C4ndrar 'V\u00E4lj filer'-knappens beteende p\u00E5 'Spel'-fliken: ist\u00E4llet f\u00F6r att v\u00E4lja enstaka ROM-filer s\u00E5 kan du v\u00E4lja mapp f\u00F6r att l\u00E4gga till alla filer som st\u00F6ds p\u00E5 en g\u00E5ng.
windowTitleAddingFiles=Letar efter filer...
windowBodyFilesScanned=Filer genoms\u00F6kta: %d\nKommer att l\u00E4ggas till: %d
tab2_Lbl_AwooBlockTitle=Awoo Installer och kompatibla
tabRcm_Lbl_Payload=Payload:
tabRcm_Lbl_FuseeGelee=Fus\u00E9e Gel\u00E9e RCM

View File

@ -0,0 +1,97 @@
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:

View File

@ -9,8 +9,9 @@ windowBodyConfirmExit=\u0417\u0430\u0440\u0430\u0437 \u0432\u0456\u0434\u0431\u0
windowTitleConfirmExit=\u041D\u0456, \u0437\u0443\u043F\u0438\u043D\u0438\u0441\u044C!
btn_Stop=\u041F\u0435\u0440\u0435\u0440\u0432\u0430\u0442\u0438
tab3_Txt_GreetingsMessage2=--\n\
\u0421\u0438\u0440\u0446\u0435\u0432\u0438\u0439 \u043A\u043E\u0434: https://github.com/developersu/ns-usbloader/\n\
\u0421\u0430\u0439\u0442: https://developersu.blogspot.com/search/label/NS-USBloader\n\
\u0421\u0438\u0440\u0446\u0435\u0432\u0438\u0439 \u043A\u043E\u0434: https://git.redrise.ru/desu/ns-usbloader\n\
\u0414\u0437\u0435\u0440\u043A\u0430\u043B\u043E: https://github.com/developersu/ns-usbloader/\n\
\u0421\u0430\u0439\u0442: https://redrise.ru\n\
\u0418\u0441\u0430\u0454\u043D\u043A\u043E \u0414\u043C\u0438\u0442\u0440\u043E [developer.su]
tab1_table_Lbl_Status=\u0421\u0442\u0430\u043D
tab1_table_Lbl_FileName=\u0406\u043C'\u044F \u0444\u0430\u0439\u043B\u0443
@ -43,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 NSP
btn_OpenSplitFile=\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0440\u043E\u0437\u0431\u0438\u0442\u0438\u0439 \u0444\u0430\u0439\u043B
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
@ -76,3 +77,20 @@ 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:

View File

@ -2,7 +2,7 @@
btn_InjectPayloader=N\u1EA1p payload
btn_OpenFile=Ch\u1ECDn t\u1EADp tin .NSP
btn_OpenSplitFile=Ch\u1ECDn NSP t\u00E1ch
btn_OpenSplitFile=Ch\u1ECDn ROM t\u00E1ch
btn_Select=Ch\u1ECDn
btn_Stop=Ng\u1EAFt
btn_Upload=T\u1EA3i l\u00EAn NS
@ -34,7 +34,11 @@ tab3_Txt_EnteredAsMsg1=B\u1EA1n \u0111\u00E3 truy nh\u1EADp d\u01B0\u1EDBi d\u1E
tab3_Txt_EnteredAsMsg2=B\u1EA1n n\u00EAn c\u00F3 quy\u1EC1n root ho\u1EB7c c\u1EA5u h\u00ECnh quy\u1EC1n 'udev' cho ng\u01B0\u1EDDi d\u00F9ng n\u00E0y \u0111\u1EC3 tr\u00E1nh c\u00E1c v\u1EA5n \u0111\u1EC1 ph\u00E1t sinh.
tab3_Txt_FilesToUploadTitle=T\u1EADp tin s\u1EBD t\u1EA3i l\u00EAn\:
tab3_Txt_GreetingsMessage=Ch\u00E0o m\u1EEBng \u0111\u1EBFn NS-USBloader
tab3_Txt_GreetingsMessage2=--\nNgu\u1ED3n\: https\://github.com/developersu/ns-usbloader/\nTrang\: https\://developersu.blogspot.com/search/label/NS-USBloader\nDmitry Isaenko [developer.su]
tab3_Txt_GreetingsMessage2=--\n\
Ngu\u1ED3n: https://git.redrise.ru/desu/ns-usbloader\n\
Mirror: https://github.com/developersu/ns-usbloader/\n\
Trang: https://redrise.ru\n\
Dmitry Isaenko [developer.su]
tab3_Txt_NoFolderOrFileSelected=Kh\u00F4ng c\u00F3 t\u1EADp tin n\u00E0o \u0111\u01B0\u1EE3c ch\u1ECDn\: kh\u00F4ng c\u00F3 g\u00EC \u0111\u1EC3 t\u1EA3i l\u00EAn.
tabSplMrg_Btn_ChangeSaveToLocation=Thay \u0111\u1ED5i
tabSplMrg_Btn_Convert=Chuy\u1EC3n \u0111\u1ED5i
@ -62,3 +66,4 @@ windowTitleNewVersionNOTAval=Ch\u01B0a c\u00F3 phi\u00EAn b\u1EA3n m\u1EDBi
windowTitleNewVersionUnknown=Kh\u00F4ng th\u1EC3 ki\u1EC3m tra phi\u00EAn b\u1EA3n m\u1EDBi
btn_Cancel=H\u1EE7y B\u1ECF

View File

@ -1,5 +1,7 @@
btn_OpenFile=\u9009\u62E9.NSP\u6587\u4EF6
btn_OpenFolders=\u9009\u62E9\u76EE\u5F55
btn_Upload=\u4E0A\u4F20\u5230NS
btn_OpenFolders_tooltip=\u6B63\u5728\u626B\u63CF\u9009\u4E2D\u7684\u76EE\u5F55.\n\u6240\u6709\u7684\u76EE\u5F55\u626B\u63CF\u5B8C\u6210.\n\u7B26\u5408\u7684\u6587\u4EF6\u5DF2\u7ECF\u6DFB\u52A0\u5230\u5217\u8868\u4E2D.
tab3_Txt_EnteredAsMsg1=\u4F60\u6B63\u5728\u4F7F\u7528:
tab3_Txt_EnteredAsMsg2=\u4F60\u5E94\u8BE5\u4F7F\u7528root\u8D26\u53F7\u6216\u8005\u4E3A\u5F53\u524D\u7528\u6237\u914D\u7F6E'udev'\u89C4\u5219\u6765\u907F\u514D\u53EF\u80FD\u7684\u95EE\u9898\u3002
tab3_Txt_FilesToUploadTitle=\u8981\u4E0A\u4F20\u7684\u6587\u4EF6:
@ -9,8 +11,9 @@ windowBodyConfirmExit=\u6570\u636E\u6B63\u5728\u4F20\u8F93\u4E2D\uFF0C\u5173\u95
windowTitleConfirmExit=\u4E0D, \u4E0D\u8FDB\u884C\u8FD9\u9879\u64CD\u4F5C\uFF01
btn_Stop=\u4E2D\u65AD
tab3_Txt_GreetingsMessage2=--\n\
\u6E90\u4EE3\u7801: https://github.com/developersu/ns-usbloader/\n\
\u7F51\u7AD9: https://developersu.blogspot.com/search/label/NS-USBloader\n\
\u6E90\u4EE3\u7801: https://git.redrise.ru/desu/ns-usbloader\n\
Mirror: https://github.com/developersu/ns-usbloader/\n\
\u7F51\u7AD9: https://redrise.ru\n\
Dmitry Isaenko [developer.su]
tab1_table_Lbl_Status=\u72B6\u6001
tab1_table_Lbl_FileName=\u6587\u4EF6\u540D
@ -41,8 +44,8 @@ windowBodyNewVersionNOTAval=\u4F60\u6B63\u5728\u4F7F\u7528\u6700\u65B0\u7248
tab2_Cb_AllowXciNszXcz=Awoo\u6A21\u5F0F\u5141\u8BB8\u9009\u62E9XCI\u6587\u4EF6
tab2_Lbl_AllowXciNszXczDesc=\u7528\u4E8E\u4E00\u4E9B\u652F\u6301XCI/NSZ/XCZ\u548CTinfoil\u4F20\u8F93\u534F\u8BAE\u7684\u7B2C\u4E09\u65B9\u5E94\u7528\u3002\u5982\u679C\u4E0D\u6E05\u695A\u4E0D\u8981\u4FEE\u6539\u3002
tab2_Lbl_Language=\u8BED\u8A00
windowBodyRestartToApplyLang=\u8BF7\u91CD\u542F\u5E94\u7528\u4EE5\u5E94\u7528\u66F4\u6539\u3002
btn_OpenSplitFile=\u9009\u62E9\u5206\u5272\u7684NSP
windowBodyRestartToApplyLang=\u8bf7\u91cd\u542f\u7a0b\u5e8f\u005c\u006e\u914d\u7f6e\u624d\u4f1a\u751f\u6548\uff01
btn_OpenSplitFile=\u9009\u62E9\u5206\u5272\u7684ROM
tab2_Lbl_ApplicationSettings=\u4E3B\u8981\u8BBE\u5B9A
tabSplMrg_Lbl_SplitNMergeTitle=\u5206\u5272&\u5408\u5E76\u6587\u4EF6\u5DE5\u5177
tabSplMrg_RadioBtn_Split=\u5206\u5272&\u5408\u5E76\u6587\u4EF6\u5DE5\u5177
@ -69,3 +72,11 @@ btn_Close=\u5173\u95ED
tab2_Cb_GlVersion=GoldLeaf\u7248\u672C
tab2_Cb_GLshowNspOnly=\u5728GoldLeaf\u5185\u4EC5\u663E\u793A*.nsp\u6587\u4EF6
windowBodyPleaseStopOtherProcessFirst=\u5982\u8981\u6267\u884C\u76EE\u524D\u7684\u64CD\u4F5C\u7A0B\u5E8F,\u8BF7\u5148\u505C\u6B62\u5176\u4ED6\u6B63\u5728\u5904\u7406\u7684\u7A0B\u5E8F.
tab2_Cb_foldersSelectorForRoms=\u9009\u4E2D\u540E\u5207\u6362\u6210\u9009\u62E9\u76EE\u5F55\u6A21\u5F0F
tab2_Cb_foldersSelectorForRomsDesc=\u542F\u7528\u6B64\u529F\u80FD\u540E\uFF0C\u5C06\u6539\u53D8\u201C\u6E38\u620F\u6807\u7B7E\u201D\u4E2D\u7684\u201C\u9009\u62E9\u6587\u4EF6\u201D\u6309\u952E\u529F\u80FD\uFF1A\u4ECE\u9009\u62E9\u4E00\u4E2A\u6587\u4EF6\u66FF\u6362\u4E3A\u9009\u62E9\u4E00\u4E2A\u76EE\u5F55\u3002
windowTitleAddingFiles=\u641C\u7D22\u6587\u4EF6\u4E2D...
windowBodyFilesScanned=\u626B\u63CF\u6587\u4EF6: %25d\n\u88AB\u6DFB\u52A0: %25d
tab2_Lbl_AwooBlockTitle=awoo installer \u5B8C\u6210
tabRcm_Lbl_Payload=Payload:
tabRcm_Lbl_FuseeGelee=Fus\u00E9e Gel\u00E9e RCM

View File

@ -1,16 +1,19 @@
btn_OpenFile=\u9078\u64C7\u6A94\u6848
btn_OpenFolders=\u9078\u64C7\u8CC7\u6599\u593E
btn_Upload=\u4E0A\u50B3\u81F3NS
btn_OpenFolders_tooltip=\u9078\u64C7\u8981\u6AA2\u67E5\u7684\u8CC7\u6599\u593E.\n\u6703\u6AA2\u67E5\u8CC7\u6599\u593E\u8207\u6240\u6709\u5B50\u76EE\u9304.\n\u6240\u6709\u7B26\u5408\u7684\u6A94\u6848\u90FD\u6703\u52A0\u5165\u4F47\u5217.
tab3_Txt_EnteredAsMsg1=\u76EE\u524D\u767B\u5165\u7684\u4F7F\u7528\u8005:
tab3_Txt_EnteredAsMsg2=\u57F7\u884C\u6B64\u64CD\u4F5C\u6642\u4F60\u5FC5\u9808\u64C1\u6709\u6700\u9AD8\u5B58\u53D6\u6B0A\u9650,\u6216\u8005\u5DF2\u914D\u7F6E\u4E86'udev'\u898F\u5247,\u4EE5\u78BA\u4FDD\u4E0D\u6703\u51FA\u73FE\u4EFB\u4F55\u554F\u984C.
tab3_Txt_EnteredAsMsg2=\u57F7\u884C\u6B64\u64CD\u4F5C\u6642\u4F60\u5FC5\u9808\u64C1\u6709\u7BA1\u7406\u54E1\u6B0A\u9650,\u6216\u6B64\u767B\u5165\u7684\u4F7F\u7528\u8005\u5E33\u6236\u5DF2\u914D\u7F6E'udev'\u898F\u5247,\u4EE5\u907F\u514D\u767C\u751F\u554F\u984C.
tab3_Txt_FilesToUploadTitle=\u4E0A\u50B3\u7684\u6A94\u6848:
tab3_Txt_GreetingsMessage=\u6B61\u8FCE\u4F7F\u7528NS-USBloader
tab3_Txt_NoFolderOrFileSelected=\u5C1A\u672A\u9078\u53D6\u6A94\u6848: \u4E0A\u50B3\u4F47\u5217\u6C92\u6709\u9805\u76EE
windowBodyConfirmExit=\u6B64\u6642\u9000\u51FA\u7A0B\u5F0F\u5C07\u6703\u4E2D\u65B7\u6B63\u5728\u50B3\u8F38\u7684\u8CC7\u6599.\n\u9019\u9805\u64CD\u4F5C\u53EF\u80FD\u6703\u9020\u6210\u4EE4\u4EBA\u5F8C\u6094\u7684\u640D\u5BB3.\n\u662F\u5426\u78BA\u8A8D\u8981\u4E2D\u65B7\u50B3\u8F38\u4E26\u4E14\u7D50\u675F\u7A0B\u5F0F?
windowBodyConfirmExit=\u6B64\u6642\u9000\u51FA\u7A0B\u5F0F\u5C07\u6703\u4E2D\u65B7\u6B63\u5728\u50B3\u8F38\u7684\u8CC7\u6599.\n\u518D\u6B21\u50B3\u8F38\u8CC7\u6599\u5C07\u91CD\u8907\u4F54\u7528\u6642\u9593.\n\u662F\u5426\u78BA\u8A8D\u8981\u4E2D\u65B7\u50B3\u8F38\u4E26\u4E14\u7D50\u675F\u7A0B\u5F0F?
windowTitleConfirmExit=\u4E0D,\u8ACB\u52FF\u9000\u51FA!
btn_Stop=\u4E2D\u65B7\u64CD\u4F5C
tab3_Txt_GreetingsMessage2=--\n\
Source: https://github.com/developersu/ns-usbloader/\n\
Site: https://developersu.blogspot.com/search/label/NS-USBloader\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=\u72C0\u614B
tab1_table_Lbl_FileName=\u6A94\u6848\u540D\u7A31
@ -28,7 +31,7 @@ tab2_Lbl_HostPort=\u9023\u63A5\u57E0
tab2_Cb_AutoDetectIp=\u81EA\u52D5\u5075\u6E2CIP
tab2_Cb_RandSelectPort=\u96A8\u6A5F\u9078\u53D6\u9023\u63A5\u57E0
tab2_Cb_DontServeRequests=\u4E0D\u56DE\u61C9NS\u8ACB\u6C42
tab2_Lbl_DontServeRequestsDesc=\u555F\u7528\u6B64\u8A2D\u5B9A\u5F8C,\u6B64\u96FB\u8166\u5C07\u4E0D\u6703\u56DE\u61C9\u4F86\u81EANS(\u900F\u904E\u7DB2\u8DEF)\u7684NSP\u6A94\u6848\u8ACB\u6C42,\u4E26\u8B93Awoo\u5C0B\u627E\u6A94\u6848\u4F86\u6E90\u6642\u4F7F\u7528\u9810\u8A2D\u7684\u4E3B\u6A5F\u8A2D\u5B9A.
tab2_Lbl_DontServeRequestsDesc=\u555F\u7528\u6B64\u8A2D\u5B9A\u5F8C,\u6B64\u96FB\u8166\u5C07\u4E0D\u6703\u56DE\u61C9\u4F86\u81EANS(\u900F\u904E\u7DB2\u8DEF)\u7684NSP\u6A94\u6848\u8ACB\u6C42,\u4E26\u8B93Awoo(\u6216\u5176\u4ED6\u540C\u985E\u578B\u7A0B\u5F0F)\u5C0B\u627E\u6A94\u6848\u4F86\u6E90\u6642\u4F7F\u7528\u9810\u8A2D\u7684\u4E3B\u6A5F\u8A2D\u5B9A.
tab2_Lbl_HostExtra=\u5176\u4ED6
windowTitleErrorPort=\u9023\u63A5\u57E0\u8A2D\u5B9A\u4E0D\u6B63\u78BA!
windowBodyErrorPort=\u9023\u63A5\u57E0\u8A2D\u5B9A\u503C\u5FC5\u9808\u4ECB\u65BC0\u523065535\u4E4B\u9593.
@ -42,7 +45,7 @@ tab2_Cb_AllowXciNszXcz=\u5141\u8A31Awoo\u6A21\u5F0F\u6642\u9078\u53D6XCI / NSZ /
tab2_Lbl_AllowXciNszXczDesc=\u6B64\u8A2D\u5B9A\u5C08\u70BA\u652F\u63F4XCI/NSZ/XCZ\u6A94\u6848\u683C\u5F0F\u8207Tinfoil\u50B3\u8F38\u5354\u8B70\u7684\u7B2C\u4E09\u65B9\u7A0B\u5F0F\u4F7F\u7528. \u5982\u4E0D\u78BA\u5B9A,\u8ACB\u52FF\u8B8A\u66F4\u6B64\u9805\u8A2D\u5B9A. \u4F7F\u7528Awoo Installer\u8ACB\u555F\u7528\u6B64\u8A2D\u5B9A.
tab2_Lbl_Language=\u4ECB\u9762\u8A9E\u7CFB
windowBodyRestartToApplyLang=\u8ACB\u91CD\u65B0\u555F\u52D5\u7A0B\u5F0F\u4EE5\u5957\u7528\u8B8A\u66F4\u7684\u8A2D\u5B9A.
btn_OpenSplitFile=\u9078\u64C7\u5206\u5272\u7684NSP
btn_OpenSplitFile=\u9078\u64C7\u5206\u5272\u7684ROM
tab2_Lbl_ApplicationSettings=\u4E3B\u8981\u8A2D\u5B9A
tabSplMrg_Lbl_SplitNMergeTitle=\u5206\u5272&\u5408\u4F75\u6A94\u6848\u5DE5\u5177
tabSplMrg_RadioBtn_Split=\u5206\u5272&\u5408\u4F75\u6A94\u6848\u5DE5\u5177
@ -55,7 +58,7 @@ tabSplMrg_Lbl_SaveToLocation=\u5132\u5B58\u8DEF\u5F91:
tabSplMrg_Btn_ChangeSaveToLocation=\u8B8A\u66F4
tabSplMrg_Btn_Convert=\u8F49\u6A94
windowTitleError=\u932F\u8AA4
windowBodyPleaseFinishTransfersFirst=\u7576\u7A0B\u5F0F\u6B63\u5728\u8655\u7406USB/Network\u5B89\u88DD\u6642\u7121\u6CD5\u540C\u6642\u57F7\u884C\u5206\u5272/\u5408\u4F75\u6A94\u6848. \u5982\u9700\u7E7C\u7E8C,\u5FC5\u9808\u4E2D\u65B7\u76EE\u524D\u7684\u50B3\u8F38.
windowBodyPleaseFinishTransfersFirst=\u7576\u7A0B\u5F0F\u6B63\u5728\u8655\u7406USB/\u7DB2\u8DEF\u5B89\u88DD\u6642\u7121\u6CD5\u540C\u6642\u57F7\u884C\u5206\u5272/\u5408\u4F75\u6A94\u6848. \u5982\u9700\u7E7C\u7E8C,\u5FC5\u9808\u4E2D\u65B7\u76EE\u524D\u7684\u50B3\u8F38.
done_txt=\u5B8C\u6210!
failure_txt=\u5931\u6557
btn_Select=\u9078\u64C7
@ -68,4 +71,12 @@ btn_Cancel=\u53D6\u6D88
btn_Close=\u95DC\u9589
tab2_Cb_GlVersion=GoldLeaf\u7248\u672C
tab2_Cb_GLshowNspOnly=\u5728GoldLeaf\u5167\u50C5\u986F\u793A*.nsp\u6A94\u6848
windowBodyPleaseStopOtherProcessFirst=\u5982\u8981\u57F7\u884C\u76EE\u524D\u7684\u64CD\u4F5C\u7A0B\u5E8F,\u8ACB\u5148\u505C\u6B62\u5176\u4ED6\u6B63\u5728\u8655\u7406\u7684\u7A0B\u5E8F.
windowBodyPleaseStopOtherProcessFirst=\u5982\u8981\u57F7\u884C\u76EE\u524D\u7684\u64CD\u4F5C\u7A0B\u5E8F,\u8ACB\u5148\u505C\u6B62\u5176\u4ED6\u6B63\u5728\u8655\u7406\u7684\u7A0B\u5E8F.
tab2_Cb_foldersSelectorForRoms=\u9078\u64C7\u6A94\u6848\u6642\u7531\u539F\u5148\u500B\u5225\u9078\u53D6\u8B8A\u66F4\u70BA\u6307\u5B9A\u8CC7\u6599\u593E\u5167\u7684\u6240\u6709\u7B26\u5408\u6A94\u6848.
tab2_Cb_foldersSelectorForRomsDesc=\u555F\u7528\u6B64\u8A2D\u5B9A\u5F8C,\u5C07\u8B8A\u66F4'\u904A\u6232\u63A7\u5236\u5668'\u5206\u9801\u4E0B\u65B9\u7684'\u9078\u64C7\u6A94\u6848'\u6309\u9215\u529F\u80FD: \u7531\u539F\u5148\u7684\u500B\u5225\u6A94\u6848\u9032\u884C\u9010\u4E00\u9078\u53D6\uFF0C\u53D6\u4EE3\u70BA\u4E00\u6B21\u52A0\u5165\u6307\u5B9A\u8CC7\u6599\u593E\u5167\u7B26\u5408\u7684\u6240\u6709\u6A94\u6848.
windowTitleAddingFiles=\u6B63\u5728\u52A0\u5165\u4F47\u5217...
windowBodyFilesScanned=\u6A94\u6848\u5DF2\u6383\u63CF:%25d\n \u5DF2\u52A0\u5165: %25d
tab2_Lbl_AwooBlockTitle=Awoo Installer \u8207\u540C\u985E\u578B\u7A0B\u5F0F
tabRcm_Lbl_Payload=Payload:
tabRcm_Lbl_FuseeGelee=Fus\u00E9e Gel\u00E9e RCM

View File

@ -5,6 +5,18 @@
-fx-background: #2d2d2d;
}
Text {
-fx-fill: white;
}
.bold-text{
-fx-font-weight: bold;
}
.italic-text{
-fx-font-style: italic;
}
.button, .buttonUp, .buttonStop, .buttonSelect{
-fx-background-color: #4f4f4f;
-fx-border-color: #4f4f4f;
@ -235,21 +247,31 @@
-fx-border-width: 2;
}
.list-cell, .list-cell:selected, .list-cell:filled:selected{
.list-cell:even,
.list-cell:even:selected,
.list-cell:even:filled:selected{
-fx-background-color: -fx-table-cell-border-color, #424242;
-fx-background-insets: 0, 0 0 1 0;
-fx-table-cell-border-color: #6d8484;
}
.list-cell:odd, .list-cell:odd:selected, .list-cell:odd:filled:selected{
.list-cell:odd,
.list-cell:odd:selected,
.list-cell:odd:filled:selected{
-fx-background-color: -fx-table-cell-border-color, #4f4f4f;
-fx-background-insets: 0, 0 0 1 0;
-fx-table-cell-border-color: #6d8484;
}
.list-cell .text, .list-cell:odd .text{
.list-cell .text,
.list-cell:odd .text,
.list-cell Text,
.list-cell:odd Text{
-fx-fill: #f7fafa;
}
.list-cell:filled:selected .text, .list-cell:odd:filled:selected .text{
.list-cell:filled:selected .text,
.list-cell:odd:filled:selected .text,
.list-cell:filled:selected Text,
.list-cell:odd:filled:selected Text{
-fx-fill: #08f3ff;
}
/* -========================== Context menu =====================- */
@ -409,6 +431,13 @@
-fx-min-height: 24;
-fx-min-width: 36;
}
.regionCake{
-fx-shape: "M4,8H8V4A2,2 0 0,1 10,2H14A2,2 0 0,1 16,4V8H20A2,2 0 0,1 22,10V14A2,2 0 0,1 20,16H16V20A2,2 0 0,1 14,22H10A2,2 0 0,1 8,20V16H4A2,2 0 0,1 2,14V10A2,2 0 0,1 4,8Z";
-fx-background-color: #71e016;
-size: 24;
-fx-min-height: -size;
-fx-min-width: -size;
}
.regionDump{
-fx-shape: "M 4.0078125 0 C 1.5078125 0 0 1.4882812 0 3.984375 L 0 15.988281 C 0 18.417969 1.4927148 20 4.0078125 20 L 6.5 20 L 6.5 0 L 4.0078125 0 z M 23.5 0 L 23.5 20 C 24.504057 19.999294 25.159942 20 25.992188 20 C 28.414062 20 30 18.496094 30 15.996094 L 30 3.9765625 C 30 1.5195311 28.508726 0 26.003906 0 L 23.5 0 z M 11.990234 2.8886719 L 11.990234 9.9003906 L 6.9902344 9.9003906 L 14.990234 20 L 22.990234 9.9003906 L 17.990234 9.9003906 C 17.990234 8.2387016 17.9999 3.6538029 18 2.8886719 L 11.990234 2.8886719 z M 3.1015625 2.9570312 C 4.1485235 2.9562481 4.9977514 3.8046013 4.9980469 4.8515625 C 4.998831 5.8992865 4.1492865 6.7488309 3.1015625 6.7480469 C 2.0546013 6.7477509 1.2062483 5.8985235 1.2070312 4.8515625 C 1.2073268 3.8053642 2.0553642 2.9573267 3.1015625 2.9570312 z M 26.865234 11.148438 C 27.912958 11.147652 28.762503 11.997198 28.761719 13.044922 C 28.761423 14.091883 27.912195 14.940236 26.865234 14.939453 C 25.819036 14.939158 24.970999 14.09112 24.970703 13.044922 C 24.96992 11.997961 25.818273 11.148733 26.865234 11.148438 z ";
-fx-background-color: #71e016;
@ -438,6 +467,7 @@
}
.nxdt.label .text {
-fx-fill: #cb0010;
-fx-font-weight: bold;
}
.regionWindows {
@ -461,7 +491,39 @@
-fx-min-height: -size;
-fx-min-width: 24;
}
//
/********************* Spinner **************************/
.spinner{
-fx-background-color: #4f4f4f;
-fx-border-radius: 3;
-fx-border-width: 1;
-fx-border-color: #4f4f4f;
-fx-mark-color: #eea11e;
-fx-effect: none;
}
.spinner .increment-arrow-button,
.spinner .decrement-arrow-button {
-fx-background-radius: 0;
-fx-background-color: #4f4f4f;
}
.spinner .increment-arrow-button:hover .increment-arrow,
.spinner .decrement-arrow-button:hover .decrement-arrow {
-fx-background-color: #ff8000;
}
.spinner .increment-arrow-button:hover:pressed .increment-arrow,
.spinner .decrement-arrow-button:hover:pressed .decrement-arrow,
.spinner .increment-arrow-button:pressed .increment-arrow,
.spinner .decrement-arrow-button:pressed .decrement-arrow {
-fx-background-color: #71e016;
}
.spinner .increment-arrow-button .increment-arrow,
.spinner .decrement-arrow-button .decrement-arrow {
-fx-background-color: #eea11e;
}
//.lineGradient {
// -fx-background-color: linear-gradient(from 41px 34px to 50px 50px, reflect, #00c8fc 30%, transparent 45%);
//}

View File

@ -5,6 +5,18 @@
-fx-background: #ebebeb;
}
Text {
-fx-fill: black;
}
.bold-text{
-fx-font-weight: bold;
}
.italic-text{
-fx-font-style: italic;
}
.button, .buttonUp, .buttonStop, .buttonSelect{
-fx-background-color: #fefefe;
-fx-background-insets: 0 0 0 0, 0, 1, 2;
@ -253,23 +265,35 @@
-fx-border-width: 2;
}
.list-cell, .list-cell:selected, .list-cell:filled:selected{
.list-cell:even{
-fx-background-color: -fx-table-cell-border-color, #ebfffe;
-fx-background-insets: 0, 0 0 1 0;
-fx-table-cell-border-color: #b0b0b0;
}
.list-cell:odd, .list-cell:odd:selected, .list-cell:odd:filled:selected{
.list-cell:odd{
-fx-background-color: -fx-table-cell-border-color, #fefefe;
-fx-background-insets: 0, 0 0 1 0;
-fx-table-cell-border-color: #b0b0b0;
}
.list-cell .text, .list-cell:odd .text{
.list-cell:even:selected,
.list-cell:even:filled:selected,
.list-cell:odd:selected,
.list-cell:odd:filled:selected{
-fx-background-color: -fx-table-cell-border-color, #e4ffde;
}
.list-cell .text,
.list-cell:odd .text,
.list-cell Text,
.list-cell:odd Text{
-fx-fill: #2c2c2c;
}
.list-cell:filled:selected .text, .list-cell:odd:filled:selected .text{
.list-cell:filled:selected .text,
.list-cell:odd:filled:selected .text,
.list-cell:filled:selected Text,
.list-cell:odd:filled:selected Text{
-fx-fill: #2c2c2c;
-fx-font-weight: bold
}
/* -========================= Separator ===================- */
.separator *.line {
@ -327,6 +351,13 @@
-fx-min-height: 24;
-fx-min-width: 36;
}
.regionCake{
-fx-shape: "M4,8H8V4A2,2 0 0,1 10,2H14A2,2 0 0,1 16,4V8H20A2,2 0 0,1 22,10V14A2,2 0 0,1 20,16H16V20A2,2 0 0,1 14,22H10A2,2 0 0,1 8,20V16H4A2,2 0 0,1 2,14V10A2,2 0 0,1 4,8Z";
-fx-background-color: #71e016;
-size: 24;
-fx-min-height: -size;
-fx-min-width: -size;
}
.regionDump{
-fx-shape: "M 4.0078125 0 C 1.5078125 0 0 1.4882812 0 3.984375 L 0 15.988281 C 0 18.417969 1.4927148 20 4.0078125 20 L 6.5 20 L 6.5 0 L 4.0078125 0 z M 23.5 0 L 23.5 20 C 24.504057 19.999294 25.159942 20 25.992188 20 C 28.414062 20 30 18.496094 30 15.996094 L 30 3.9765625 C 30 1.5195311 28.508726 0 26.003906 0 L 23.5 0 z M 11.990234 2.8886719 L 11.990234 9.9003906 L 6.9902344 9.9003906 L 14.990234 20 L 22.990234 9.9003906 L 17.990234 9.9003906 C 17.990234 8.2387016 17.9999 3.6538029 18 2.8886719 L 11.990234 2.8886719 z M 3.1015625 2.9570312 C 4.1485235 2.9562481 4.9977514 3.8046013 4.9980469 4.8515625 C 4.998831 5.8992865 4.1492865 6.7488309 3.1015625 6.7480469 C 2.0546013 6.7477509 1.2062483 5.8985235 1.2070312 4.8515625 C 1.2073268 3.8053642 2.0553642 2.9573267 3.1015625 2.9570312 z M 26.865234 11.148438 C 27.912958 11.147652 28.762503 11.997198 28.761719 13.044922 C 28.761423 14.091883 27.912195 14.940236 26.865234 14.939453 C 25.819036 14.939158 24.970999 14.09112 24.970703 13.044922 C 24.96992 11.997961 25.818273 11.148733 26.865234 11.148438 z ";
-fx-background-color: #71e016;
@ -356,6 +387,7 @@
}
.nxdt.label .text {
-fx-fill: #9d010e;
-fx-font-weight: bold;
}
.regionWindows {
-fx-shape: "M3,12V6.75L9,5.43V11.91L3,12M20,3V11.75L10,11.9V5.21L20,3M3,13L9,13.09V19.9L3,18.75V13M20,13.25V22L10,20.09V13.1L20,13.25Z";

Some files were not shown because too many files have changed in this diff Show More