Merge with master (#1)

This commit is contained in:
R-YaTian 2024-12-23 09:36:24 +08:00 committed by GitHub
parent aedaa22c5e
commit fd449181f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 570 additions and 390 deletions

View file

@ -0,0 +1,82 @@
steps:
- name: test-standard
when:
event: [tag, push]
image: maven:3-openjdk-17
commands:
- mvn -B -DskipTests clean package
- mvn test -B
- echo target/ns-usbloader-*jar
- mkdir artifacts
- cp target/ns-usbloader-*jar artifacts
volumes:
- /home/docker/woodpecker/files/m2:/root/.m2
- name: make-windows-installer
when:
event: [tag, push]
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 "../../../artifacts"
- rm ./NS-USBloader.exe
- rm ./Installer-*.exe
- cd ../../../
volumes:
- /home/docker/woodpecker/files/assembly/openjdk-19.0.2:/assembly/jdk
- /home/docker/woodpecker/files/assembly/Drivers_set.exe:/assembly/Drivers_set.exe
- name: emerge-legacy-artifact
when:
event: [tag, push]
image: maven:3-openjdk-17
commands:
- . ./.make_legacy
- mvn -B -DskipTests clean package
- echo target/ns-usbloader-*jar
- cp target/ns-usbloader-*jar artifacts
volumes:
- /home/docker/woodpecker/files/m2:/root/.m2
- name: make-legacy-windows-installer
when:
event: [tag, push]
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 "../../../artifacts"
- cd ../../../
volumes:
- /home/docker/woodpecker/files/assembly/openjdk-19.0.2:/assembly/jdk
- /home/docker/woodpecker/files/assembly/Drivers_set.exe:/assembly/Drivers_set.exe
- name: emerge-mac-m1-artifact
when:
event: [tag, push]
image: maven:3-openjdk-17
commands:
- . ./.make_m1
- mvn -B -DskipTests clean package
- echo target/ns-usbloader-*jar
- cp target/ns-usbloader-*jar artifacts
volumes:
- /home/docker/woodpecker/files/m2:/root/.m2
- name: save-artifacts
when:
event: [tag, push]
image: alpine:latest
commands:
- export ARTIFACTS_DIR="$(date -d @$CI_PIPELINE_CREATED +'%Y-%m-%d %H:%m %Z')"
- mkdir -p /builds/ns-usbloader/
- mv artifacts "/builds/ns-usbloader/$ARTIFACTS_DIR"
volumes:
- /home/www/builds:/builds

View file

@ -1,6 +1,6 @@
<h1 align="center"><img src="screenshots/ApplicationLogo.svg" alt="NS-USBloader" width="450px"/></h1> <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) [![Build Status](https://ci.redrise.ru/api/badges/desu/ns-usbloader/status.svg)](https://ci.redrise.ru/desu/ns-usbloader) ![License](https://img.shields.io/badge/License-GPLv3-blue.svg) ![Releases](https://img.shields.io/github/downloads/developersu/ns-usbloader/total.svg) ![LatestVer](https://img.shields.io/github/release/developersu/ns-usbloader.svg) [![status-badge](https://ci.redrise.ru/api/badges/12/status.svg)](https://ci.redrise.ru/repos/12)
NS-USBloader is: 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.
@ -59,6 +59,7 @@ Sometimes I add new posts about this project [on my blog page](https://developer
* Swedish by [Daniel Nylander](https://github.com/yeager) * Swedish by [Daniel Nylander](https://github.com/yeager)
* Japanese by [kuragehime](https://github.com/kuragehimekurara1) * Japanese by [kuragehime](https://github.com/kuragehimekurara1)
* Ryukyuan languages by [kuragehime](https://github.com/kuragehimekurara1) * Ryukyuan languages by [kuragehime](https://github.com/kuragehimekurara1)
* Turkish language by [Erimsaholut](https://github.com/Erimsaholut)
* Angelo Elias Dalzotto makes packages in AUR * Angelo Elias Dalzotto makes packages in AUR
* Phoenix[Msc] provides his shiny Mac M1 for debug * Phoenix[Msc] provides his shiny Mac M1 for debug
@ -256,17 +257,6 @@ If you like this app, just give a star (@ GitHub).
This is non-commercial project. This is non-commercial project.
Nevertheless, I'll be more than happy if you find a chance to make a donation for charity to people I trust:
* BTC → 1BnErE3n6LEdEjvvFrt4FMdXd1UGa5L7Ge
* ETH → 0x9c29418129553bE171181bb6245151aa0576A3b7
* DOT → 15BWSwmA4xEHZdq3gGftWg7dctMQk9vXwqA92Pg22gsxDweF
* LTC → ltc1qfjvzxm04tax077ra9rvmxdnsum8alws2n20fag
* ETC → 0xe9064De288C8454942533a005AB72515e689226E
* USDT (TRC20) → TKgp5SvJGiqYNFtvJfEDGLFbezFEHq1tBy
* USDT (ERC20) → 0x9c29418129553bE171181bb6245151aa0576A3b7
* XRP → rGmGaLsKmSUbxWfyi4mujtVamTzj3Nqxbw.
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. 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

@ -91,8 +91,8 @@
Section "NS-USBloader" Install Section "NS-USBloader" Install
SetOutPath "$INSTDIR" SetOutPath "$INSTDIR"
file /r jdk file /r \assembly\jdk
file Drivers_set.exe file \assembly\Drivers_set.exe
file NS-USBloader.exe file NS-USBloader.exe
file logo.ico file logo.ico

View file

@ -8,7 +8,7 @@
<name>NS-USBloader</name> <name>NS-USBloader</name>
<artifactId>ns-usbloader</artifactId> <artifactId>ns-usbloader</artifactId>
<version>7.1</version> <!-- linked via script to NSIS system. Should have format of 2 blocks of numbers --> <version>7.2</version> <!-- linked via script to NSIS system. Should have format of 2 blocks of numbers -->
<url>https://redrise.ru</url> <url>https://redrise.ru</url>
<description>NS multi-tool</description> <description>NS multi-tool</description>

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -39,10 +39,13 @@ import java.util.ResourceBundle;
public class FilesDropHandle { public class FilesDropHandle {
public FilesDropHandle(List<File> files, String filesRegex, String foldersRegex){ public FilesDropHandle(List<File> files,
String filesRegex,
String foldersRegex,
NSTableViewController tableController){
FilesDropHandleTask filesDropHandleTask = new FilesDropHandleTask(files, filesRegex, foldersRegex); FilesDropHandleTask filesDropHandleTask = new FilesDropHandleTask(files, filesRegex, foldersRegex);
ResourceBundle resourceBundle = MediatorControl.getInstance().getResourceBundle(); ResourceBundle resourceBundle = MediatorControl.INSTANCE.getResourceBundle();
Button cancelButton = new Button(resourceBundle.getString("btn_Cancel")); Button cancelButton = new Button(resourceBundle.getString("btn_Cancel"));
ProgressIndicator progressIndicator = new ProgressIndicator(); ProgressIndicator progressIndicator = new ProgressIndicator();
@ -101,7 +104,7 @@ public class FilesDropHandle {
List<File> allFiles = filesDropHandleTask.getValue(); List<File> allFiles = filesDropHandleTask.getValue();
if (! allFiles.isEmpty()) { if (! allFiles.isEmpty()) {
MediatorControl.getInstance().getGamesController().tableFilesListController.setFiles(allFiles); tableController.setFiles(allFiles);
} }
stage.close(); stage.close();
}); });

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -32,7 +32,7 @@ public class FilesDropHandleTask extends Task<List<File>> {
private final List<File> filesDropped; private final List<File> filesDropped;
private final List<File> allFiles; private final List<File> allFiles;
private String messageTemplate; private final String messageTemplate;
private long filesScanned = 0; private long filesScanned = 0;
private long filesAdded = 0; private long filesAdded = 0;
@ -43,12 +43,12 @@ public class FilesDropHandleTask extends Task<List<File>> {
this.filesRegex = filesRegex; this.filesRegex = filesRegex;
this.foldersRegex = foldersRegex; this.foldersRegex = foldersRegex;
this.allFiles = new ArrayList<>(); this.allFiles = new ArrayList<>();
this.messageTemplate = MediatorControl.getInstance().getResourceBundle().getString("windowBodyFilesScanned"); this.messageTemplate = MediatorControl.INSTANCE.getResourceBundle().getString("windowBodyFilesScanned");
} }
@Override @Override
protected List<File> call() { protected List<File> call() {
if (filesDropped == null || filesDropped.size() == 0) if (filesDropped == null || filesDropped.isEmpty())
return allFiles; return allFiles;
for (File file : filesDropped){ for (File file : filesDropped){

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2023 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -142,7 +142,9 @@ public class FontSettingsController implements Initializable {
final double fontSize = fontSizeSpinner.getValue().intValue(); final double fontSize = fontSizeSpinner.getValue().intValue();
preferences.setFontStyle(fontFamily, fontSize); preferences.setFontStyle(fontFamily, fontSize);
MediatorControl.getInstance().updateApplicationFont(fontFamily, fontSize);
MediatorControl.INSTANCE.getLogArea().getScene().getRoot().setStyle(
String.format("-fx-font-family: \"%s\"; -fx-font-size: %.0f;", fontFamily, fontSize));
closeWindow(); closeWindow();
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko, wolfposd Copyright 2019-2024 Dmitry Isaenko, wolfposd
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -31,6 +31,7 @@ import javafx.scene.layout.Region;
import javafx.stage.DirectoryChooser; import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import nsusbloader.AppPreferences; import nsusbloader.AppPreferences;
import nsusbloader.NSLDataTypes.EFileStatus;
import nsusbloader.com.net.NETCommunications; import nsusbloader.com.net.NETCommunications;
import nsusbloader.com.usb.UsbCommunications; import nsusbloader.com.usb.UsbCommunications;
import nsusbloader.FilesHelper; import nsusbloader.FilesHelper;
@ -45,12 +46,14 @@ import java.util.*;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
public class GamesController implements Initializable { public class GamesController implements Initializable, ISubscriber {
private static final String REGEX_ONLY_NSP = ".*\\.nsp$"; private static final String REGEX_ONLY_NSP = ".*\\.nsp$";
private static final String REGEX_ALLFILES_TINFOIL = ".*\\.(nsp$|xci$|nsz$|xcz$)"; private static final String REGEX_ALLFILES_TINFOIL = ".*\\.(nsp$|xci$|nsz$|xcz$)";
private static final String REGEX_ALLFILES = ".*"; private static final String REGEX_ALLFILES = ".*";
private static final MediatorControl mediator = MediatorControl.INSTANCE;
@FXML @FXML
private AnchorPane usbNetPane; private AnchorPane usbNetPane;
@ -63,7 +66,7 @@ public class GamesController implements Initializable {
@FXML @FXML
private Button switchThemeBtn; private Button switchThemeBtn;
@FXML @FXML
public NSTableViewController tableFilesListController; // Accessible from Mediator (for drag-n-drop support) private NSTableViewController tableFilesListController;
@FXML @FXML
private Button selectNspBtn, selectSplitBtn, uploadStopBtn; private Button selectNspBtn, selectSplitBtn, uploadStopBtn;
@ -101,6 +104,7 @@ public class GamesController implements Initializable {
disableUploadStopBtn(tableFilesListController.isFilesForUploadListEmpty()); disableUploadStopBtn(tableFilesListController.isFilesForUploadListEmpty());
}); // Add listener to notify tableView controller }); // Add listener to notify tableView controller
tableFilesListController.setNewProtocol(getSelectedProtocolByName()); // Notify tableView controller tableFilesListController.setNewProtocol(getSelectedProtocolByName()); // Notify tableView controller
tableFilesListController.setGamesController(this);
ObservableList<String> choiceNetUsbList = FXCollections.observableArrayList("USB", "NET"); ObservableList<String> choiceNetUsbList = FXCollections.observableArrayList("USB", "NET");
choiceNetUsb.setItems(choiceNetUsbList); choiceNetUsb.setItems(choiceNetUsbList);
@ -204,11 +208,11 @@ public class GamesController implements Initializable {
} }
private boolean isAllFiletypesAllowedForGL() { private boolean isAllFiletypesAllowedForGL() {
return ! MediatorControl.getInstance().getSettingsController().getGoldleafSettings().getNSPFileFilterForGL(); return ! mediator.getSettingsController().getGoldleafSettings().getNSPFileFilterForGL();
} }
private boolean isXciNszXczSupport() { private boolean isXciNszXczSupport() {
return MediatorControl.getInstance().getSettingsController().getTinfoilSettings().isXciNszXczSupport(); return mediator.getSettingsController().getTinfoilSettings().isXciNszXczSupport();
} }
/** /**
@ -216,7 +220,7 @@ public class GamesController implements Initializable {
* tinfoil + xcinszxcz </br> * tinfoil + xcinszxcz </br>
* tinfoil + nsponly </br> * tinfoil + nsponly </br>
* goldleaf </br> * goldleaf </br>
* etc.. * etc...
*/ */
private String getRegexForFiles() { private String getRegexForFiles() {
if (isTinfoil() && isXciNszXczSupport()) if (isTinfoil() && isXciNszXczSupport())
@ -368,56 +372,58 @@ public class GamesController implements Initializable {
if (workThread != null && workThread.isAlive()) if (workThread != null && workThread.isAlive())
return; return;
// Collect files
List<File> nspToUpload;
TextArea logArea = MediatorControl.getInstance().getContoller().logArea;
if (isTinfoil() && tableFilesListController.getFilesForUpload() == null) { if (isTinfoil() && tableFilesListController.getFilesForUpload() == null) {
logArea.setText(resourceBundle.getString("tab3_Txt_NoFolderOrFileSelected")); ServiceWindow.getInfoNotification("(o_o\")", resourceBundle.getString("tab3_Txt_NoFolderOrFileSelected"));
return; return;
} }
if ((nspToUpload = tableFilesListController.getFilesForUpload()) != null){ // Collect files
List<File> nspToUpload = tableFilesListController.getFilesForUpload();
if (nspToUpload == null)
nspToUpload = new ArrayList<>();
//todo: add to make it visible
/*
else {
TextArea logArea = mediator.getLogArea();
logArea.setText(resourceBundle.getString("tab3_Txt_FilesToUploadTitle")+"\n"); logArea.setText(resourceBundle.getString("tab3_Txt_FilesToUploadTitle")+"\n");
nspToUpload.forEach(item -> logArea.appendText(" "+item.getAbsolutePath()+"\n")); nspToUpload.forEach(item -> logArea.appendText(" "+item.getAbsolutePath()+"\n"));
} }
else { */
logArea.clear();
nspToUpload = new LinkedList<>();
}
SettingsController settings = MediatorControl.getInstance().getSettingsController(); SettingsController settings = mediator.getSettingsController();
// If USB selected // If USB selected
if (isGoldLeaf()){ if (isGoldLeaf()){
final SettingsBlockGoldleafController goldleafSettings = settings.getGoldleafSettings(); final SettingsBlockGoldleafController goldleafSettings = settings.getGoldleafSettings();
usbNetCommunications = new UsbCommunications(nspToUpload, "GoldLeaf" + goldleafSettings.getGlVer(), goldleafSettings.getNSPFileFilterForGL()); usbNetCommunications = new UsbCommunications(nspToUpload, "GoldLeaf" + goldleafSettings.getGlVer(), goldleafSettings.getNSPFileFilterForGL());
} }
else if (( isTinfoil() && getSelectedNetUsb().equals("USB") )){ else {
usbNetCommunications = new UsbCommunications(nspToUpload, "TinFoil", false); if (getSelectedNetUsb().equals("USB")){
} usbNetCommunications = new UsbCommunications(nspToUpload, "TinFoil", false);
else { // NET INSTALL OVER TINFOIL
final String ipValidationPattern = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
final SettingsBlockTinfoilController tinfoilSettings = settings.getTinfoilSettings();
if (tinfoilSettings.isValidateNSHostName() && ! getNsIp().matches(ipValidationPattern)) {
if (!ServiceWindow.getConfirmationWindow(resourceBundle.getString("windowTitleBadIp"), resourceBundle.getString("windowBodyBadIp")))
return;
} }
else { // NET INSTALL OVER TINFOIL
final String ipValidationPattern = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
final SettingsBlockTinfoilController tinfoilSettings = settings.getTinfoilSettings();
String nsIP = getNsIp(); if (tinfoilSettings.isValidateNSHostName() && ! getNsIp().matches(ipValidationPattern)) {
if (!ServiceWindow.getConfirmationWindow(resourceBundle.getString("windowTitleBadIp"), resourceBundle.getString("windowBodyBadIp")))
return;
}
if (! tinfoilSettings.isExpertModeSelected()) String nsIP = getNsIp();
usbNetCommunications = new NETCommunications(nspToUpload, nsIP, false, "", "", "");
else { if (! tinfoilSettings.isExpertModeSelected())
usbNetCommunications = new NETCommunications( usbNetCommunications = new NETCommunications(nspToUpload, nsIP, false, "", "", "");
nspToUpload, else {
nsIP, usbNetCommunications = new NETCommunications(
tinfoilSettings.isNoRequestsServe(), nspToUpload,
tinfoilSettings.isAutoDetectIp()?"":tinfoilSettings.getHostIp(), nsIP,
tinfoilSettings.isRandomlySelectPort()?"":tinfoilSettings.getHostPort(), tinfoilSettings.isNoRequestsServe(),
tinfoilSettings.isNoRequestsServe()?tinfoilSettings.getHostExtra():"" tinfoilSettings.isAutoDetectIp()?"":tinfoilSettings.getHostIp(),
); tinfoilSettings.isRandomlySelectPort()?"":tinfoilSettings.getHostPort(),
tinfoilSettings.isNoRequestsServe()?tinfoilSettings.getHostExtra():""
);
}
} }
} }
workThread = new Thread(usbNetCommunications); workThread = new Thread(usbNetCommunications);
@ -446,7 +452,7 @@ public class GamesController implements Initializable {
* */ * */
@FXML @FXML
private void handleDragOver(DragEvent event){ private void handleDragOver(DragEvent event){
if (event.getDragboard().hasFiles() && ! MediatorControl.getInstance().getTransferActive()) if (event.getDragboard().hasFiles() && ! mediator.getTransferActive())
event.acceptTransferModes(TransferMode.ANY); event.acceptTransferModes(TransferMode.ANY);
event.consume(); event.consume();
} }
@ -456,47 +462,15 @@ public class GamesController implements Initializable {
@FXML @FXML
private void handleDrop(DragEvent event) { private void handleDrop(DragEvent event) {
List<File> files = event.getDragboard().getFiles(); List<File> files = event.getDragboard().getFiles();
new FilesDropHandle(files, getRegexForFiles(), getRegexForFolders()); new FilesDropHandle(files, getRegexForFiles(), getRegexForFolders(), tableFilesListController);
event.setDropCompleted(true); event.setDropCompleted(true);
event.consume(); event.consume();
} }
/** /**
* This thing modify UI for reusing 'Upload to NS' button and make functionality set for "Stop transmission" * This function called from NSTableViewController
* Called from mediator
* TODO: remove shitcoding practices
* */ * */
public void notifyThreadStarted(boolean isActive, EModule type){ void disableUploadStopBtn(boolean disable){
if (! type.equals(EModule.USB_NET_TRANSFERS)){
usbNetPane.setDisable(isActive);
return;
}
selectNspBtn.setDisable(isActive);
selectSplitBtn.setDisable(isActive);
btnUpStopImage.getStyleClass().clear();
if (isActive) {
btnUpStopImage.getStyleClass().add("regionStop");
uploadStopBtn.setOnAction(e-> stopBtnAction());
uploadStopBtn.setText(resourceBundle.getString("btn_Stop"));
uploadStopBtn.getStyleClass().remove("buttonUp");
uploadStopBtn.getStyleClass().add("buttonStop");
}
else {
btnUpStopImage.getStyleClass().add("regionUpload");
uploadStopBtn.setOnAction(e-> uploadBtnAction());
uploadStopBtn.setText(resourceBundle.getString("btn_Upload"));
uploadStopBtn.getStyleClass().remove("buttonStop");
uploadStopBtn.getStyleClass().add("buttonUp");
}
}
/**
* Crunch. This function called from NSTableViewController
* */
public void disableUploadStopBtn(boolean disable){
if (isTinfoil()) if (isTinfoil())
uploadStopBtn.setDisable(disable); uploadStopBtn.setDisable(disable);
else else
@ -515,11 +489,8 @@ public class GamesController implements Initializable {
}).start(); }).start();
} }
public void updateFilesSelectorButtonBehaviour(boolean isDirectoryChooser){ void setFilesSelectorButtonBehaviour(boolean isDirectoryChooser){
btnSelectImage.getStyleClass().clear(); btnSelectImage.getStyleClass().clear();
setFilesSelectorButtonBehaviour(isDirectoryChooser);
}
private void setFilesSelectorButtonBehaviour(boolean isDirectoryChooser){
if (isDirectoryChooser){ if (isDirectoryChooser){
selectNspBtn.setOnAction(e -> selectFoldersBtnAction()); selectNspBtn.setOnAction(e -> selectFoldersBtnAction());
btnSelectImage.getStyleClass().add("regionScanFolders"); btnSelectImage.getStyleClass().add("regionScanFolders");
@ -535,7 +506,7 @@ public class GamesController implements Initializable {
/** /**
* Get 'Recent' path * Get 'Recent' path
*/ */
public String getRecentPath(){ private String getRecentPath(){
return previouslyOpenedPath; return previouslyOpenedPath;
} }
@ -547,4 +518,42 @@ public class GamesController implements Initializable {
preferences.setNetUsb(getSelectedNetUsb()); preferences.setNetUsb(getSelectedNetUsb());
preferences.setNsIp(getNsIp()); preferences.setNsIp(getNsIp());
} }
/**
* This thing modifies UI for reusing 'Upload to NS' button and make functionality set for "Stop transmission"
* */
@Override
public void notify(EModule type, boolean isActive, Payload payload) {
if (! type.equals(EModule.USB_NET_TRANSFERS)){
usbNetPane.setDisable(isActive);
return;
}
selectNspBtn.setDisable(isActive);
selectSplitBtn.setDisable(isActive);
btnUpStopImage.getStyleClass().clear();
if (isActive) {
btnUpStopImage.getStyleClass().add("regionStop");
uploadStopBtn.setOnAction(e-> stopBtnAction());
uploadStopBtn.setText(resourceBundle.getString("btn_Stop"));
uploadStopBtn.getStyleClass().remove("buttonUp");
uploadStopBtn.getStyleClass().add("buttonStop");
return;
}
btnUpStopImage.getStyleClass().add("regionUpload");
uploadStopBtn.setOnAction(e-> uploadBtnAction());
uploadStopBtn.setText(resourceBundle.getString("btn_Upload"));
uploadStopBtn.getStyleClass().remove("buttonStop");
uploadStopBtn.getStyleClass().add("buttonUp");
Map<String, EFileStatus> statusMap = payload.getStatusMap();
if (! statusMap.isEmpty()) {
for (String key : statusMap.keySet())
tableFilesListController.setFileStatus(key, statusMap.get(key));
}
}
} }

View file

@ -0,0 +1,25 @@
/*
Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader.
NS-USBloader is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
NS-USBloader is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
*/
package nsusbloader.Controllers;
import nsusbloader.NSLDataTypes.EModule;
public interface ISubscriber {
void notify(EModule type, boolean status, Payload payload);
}

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -18,7 +18,6 @@
*/ */
package nsusbloader.Controllers; package nsusbloader.Controllers;
import javafx.application.HostServices;
import javafx.concurrent.Task; import javafx.concurrent.Task;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
@ -35,10 +34,10 @@ public class NSLMainController implements Initializable {
private ResourceBundle resourceBundle; private ResourceBundle resourceBundle;
@FXML @FXML
public TextArea logArea; // Accessible from Mediator private TextArea logArea;
@FXML @FXML
public ProgressBar progressBar; // Accessible from Mediator private ProgressBar progressBar;
@FXML @FXML
private TabPane mainTabPane; private TabPane mainTabPane;
@ -68,8 +67,6 @@ public class NSLMainController implements Initializable {
logArea.appendText(rb.getString("tab3_Txt_GreetingsMessage2")+"\n"); logArea.appendText(rb.getString("tab3_Txt_GreetingsMessage2")+"\n");
MediatorControl.getInstance().setController(this);
AppPreferences preferences = AppPreferences.getInstance(); AppPreferences preferences = AppPreferences.getInstance();
if (preferences.getAutoCheckUpdates()) if (preferences.getAutoCheckUpdates())
@ -79,6 +76,22 @@ public class NSLMainController implements Initializable {
mainTabPane.getTabs().remove(3); mainTabPane.getTabs().remove(3);
openLastOpenedTab(); openLastOpenedTab();
TransfersPublisher transfersPublisher = new TransfersPublisher(
GamesTabController,
SplitMergeTabController,
RcmTabController,
NXDTabController,
PatchesTabController);
MediatorControl.INSTANCE.configure(
resourceBundle,
SettingsTabController,
logArea,
progressBar,
GamesTabController,
transfersPublisher);
} }
private void checkForUpdates(){ private void checkForUpdates(){
Task<List<String>> updTask = new UpdatesChecker(); Task<List<String>> updTask = new UpdatesChecker();
@ -101,40 +114,7 @@ public class NSLMainController implements Initializable {
updates.setDaemon(true); updates.setDaemon(true);
updates.start(); updates.start();
} }
/**
* Get resources
* TODO: Find better solution; used in UsbCommunications() -> GL -> SelectFile command
* @return ResourceBundle
*/
public ResourceBundle getResourceBundle() {
return resourceBundle;
}
/**
* Provide hostServices to Settings tab
* */
public void setHostServices(HostServices hs ){ SettingsTabController.getGenericSettings().registerHostServices(hs);}
/**
* Get 'Settings' controller
* Used by FrontController
* */
public SettingsController getSettingsCtrlr(){
return SettingsTabController;
}
public GamesController getGamesCtrlr(){
return GamesTabController;
}
public SplitMergeController getSmCtrlr(){
return SplitMergeTabController;
}
public RcmController getRcmCtrlr(){ return RcmTabController; }
public NxdtController getNXDTabController(){ return NXDTabController; }
public PatchesController getPatchesTabController(){ return PatchesTabController; }
/** /**
* Save preferences before exit * Save preferences before exit
* */ * */

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko, wolfposd Copyright 2019-2024 Dmitry Isaenko, wolfposd
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -42,6 +42,8 @@ public class NSTableViewController implements Initializable {
private TableView<NSLRowModel> table; private TableView<NSLRowModel> table;
private ObservableList<NSLRowModel> rowsObsLst; private ObservableList<NSLRowModel> rowsObsLst;
private GamesController gamesController;
@Override @Override
public void initialize(URL url, ResourceBundle resourceBundle) { public void initialize(URL url, ResourceBundle resourceBundle) {
rowsObsLst = FXCollections.observableArrayList(); rowsObsLst = FXCollections.observableArrayList();
@ -52,10 +54,10 @@ public class NSTableViewController implements Initializable {
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.setOnKeyPressed(keyEvent -> { table.setOnKeyPressed(keyEvent -> {
if (!rowsObsLst.isEmpty()) { if (!rowsObsLst.isEmpty()) {
if (keyEvent.getCode() == KeyCode.DELETE && !MediatorControl.getInstance().getTransferActive()) { if (keyEvent.getCode() == KeyCode.DELETE && !MediatorControl.INSTANCE.getTransferActive()) {
rowsObsLst.removeAll(table.getSelectionModel().getSelectedItems()); rowsObsLst.removeAll(table.getSelectionModel().getSelectedItems());
if (rowsObsLst.isEmpty()) if (rowsObsLst.isEmpty())
MediatorControl.getInstance().getGamesController().disableUploadStopBtn(true); // TODO: change to something better gamesController.disableUploadStopBtn(true);
table.refresh(); table.refresh();
} else if (keyEvent.getCode() == KeyCode.SPACE) { } else if (keyEvent.getCode() == KeyCode.SPACE) {
for (NSLRowModel item : table.getSelectionModel().getSelectedItems()) { for (NSLRowModel item : table.getSelectionModel().getSelectedItems()) {
@ -173,13 +175,13 @@ public class NSTableViewController implements Initializable {
deleteMenuItem.setOnAction(actionEvent -> { deleteMenuItem.setOnAction(actionEvent -> {
rowsObsLst.remove(row.getItem()); rowsObsLst.remove(row.getItem());
if (rowsObsLst.isEmpty()) if (rowsObsLst.isEmpty())
MediatorControl.getInstance().getGamesController().disableUploadStopBtn(true); // TODO: change to something better gamesController.disableUploadStopBtn(true);
table.refresh(); table.refresh();
}); });
MenuItem deleteAllMenuItem = new MenuItem(resourceBundle.getString("tab1_table_contextMenu_Btn_DeleteAll")); MenuItem deleteAllMenuItem = new MenuItem(resourceBundle.getString("tab1_table_contextMenu_Btn_DeleteAll"));
deleteAllMenuItem.setOnAction(actionEvent -> { deleteAllMenuItem.setOnAction(actionEvent -> {
rowsObsLst.clear(); rowsObsLst.clear();
MediatorControl.getInstance().getGamesController().disableUploadStopBtn(true); // TODO: change to something better gamesController.disableUploadStopBtn(true);
table.refresh(); table.refresh();
}); });
MenuItem selectAllMenuItem = new MenuItem(resourceBundle.getString("tab1_table_contextMenu_Btn_SelectAll")); MenuItem selectAllMenuItem = new MenuItem(resourceBundle.getString("tab1_table_contextMenu_Btn_SelectAll"));
@ -201,7 +203,7 @@ public class NSTableViewController implements Initializable {
Bindings.when( Bindings.when(
Bindings.isNotNull( Bindings.isNotNull(
row.itemProperty())) row.itemProperty()))
.then(MediatorControl.getInstance().getTransferActive()?null:contextMenu) .then(MediatorControl.INSTANCE.getTransferActive()?null:contextMenu)
.otherwise((ContextMenu) null) .otherwise((ContextMenu) null)
); );
// Just.. don't ask.. // Just.. don't ask..
@ -222,6 +224,11 @@ public class NSTableViewController implements Initializable {
table.getColumns().add(fileSizeColumn); table.getColumns().add(fileSizeColumn);
table.getColumns().add(uploadColumn); table.getColumns().add(uploadColumn);
} }
public void setGamesController(GamesController gamesController) {
this.gamesController = gamesController;
}
/** /**
* Add single file when user selected it (Split file usually) * Add single file when user selected it (Split file usually)
* */ * */
@ -236,7 +243,7 @@ public class NSTableViewController implements Initializable {
} }
else { else {
rowsObsLst.add(new NSLRowModel(file, true)); rowsObsLst.add(new NSLRowModel(file, true));
MediatorControl.getInstance().getGamesController().disableUploadStopBtn(false); // TODO: change to something better gamesController.disableUploadStopBtn(false);
} }
table.refresh(); table.refresh();
} }
@ -256,7 +263,7 @@ public class NSTableViewController implements Initializable {
else { else {
for (File file: newFiles) for (File file: newFiles)
rowsObsLst.add(new NSLRowModel(file, true)); rowsObsLst.add(new NSLRowModel(file, true));
MediatorControl.getInstance().getGamesController().disableUploadStopBtn(false); // TODO: change to something better gamesController.disableUploadStopBtn(false);
} }
//rowsObsLst.get(0).setMarkForUpload(true); //rowsObsLst.get(0).setMarkForUpload(true);
table.refresh(); table.refresh();

View file

@ -25,8 +25,6 @@ import javafx.scene.control.Label;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.stage.DirectoryChooser; import javafx.stage.DirectoryChooser;
import nsusbloader.AppPreferences; import nsusbloader.AppPreferences;
import nsusbloader.FilesHelper;
import nsusbloader.MediatorControl;
import nsusbloader.ModelControllers.CancellableRunnable; import nsusbloader.ModelControllers.CancellableRunnable;
import nsusbloader.NSLDataTypes.EModule; import nsusbloader.NSLDataTypes.EModule;
import nsusbloader.Utilities.nxdumptool.NxdtTask; import nsusbloader.Utilities.nxdumptool.NxdtTask;
@ -35,7 +33,7 @@ import java.io.File;
import java.net.URL; import java.net.URL;
import java.util.ResourceBundle; import java.util.ResourceBundle;
public class NxdtController implements Initializable { public class NxdtController implements Initializable, ISubscriber {
@FXML @FXML
private Label saveToLocationLbl, statusLbl; private Label saveToLocationLbl, statusLbl;
@ -79,7 +77,6 @@ public class NxdtController implements Initializable {
* */ * */
private void startDumpProcess(){ private void startDumpProcess(){
if ((workThread == null || ! workThread.isAlive())){ if ((workThread == null || ! workThread.isAlive())){
MediatorControl.getInstance().getContoller().logArea.clear();
nxdtTask = new NxdtTask(saveToLocationLbl.getText()); nxdtTask = new NxdtTask(saveToLocationLbl.getText());
workThread = new Thread(nxdtTask); workThread = new Thread(nxdtTask);
@ -97,12 +94,22 @@ public class NxdtController implements Initializable {
} }
} }
public void notifyThreadStarted(boolean isActive, EModule type){ /**
* Save application settings on exit
* */
public void updatePreferencesOnExit(){
AppPreferences.getInstance().setNXDTSaveToLocation(saveToLocationLbl.getText());
}
@Override
public void notify(EModule type, boolean isActive, Payload payload) {
if (! type.equals(EModule.NXDT)){ if (! type.equals(EModule.NXDT)){
injectPldBtn.setDisable(isActive); injectPldBtn.setDisable(isActive);
return; return;
} }
statusLbl.setText(payload.getMessage());
if (isActive) { if (isActive) {
btnDumpStopImage.getStyleClass().clear(); btnDumpStopImage.getStyleClass().clear();
btnDumpStopImage.getStyleClass().add("regionStop"); btnDumpStopImage.getStyleClass().add("regionStop");
@ -121,16 +128,4 @@ public class NxdtController implements Initializable {
injectPldBtn.getStyleClass().remove("buttonStop"); injectPldBtn.getStyleClass().remove("buttonStop");
injectPldBtn.getStyleClass().add("buttonUp"); injectPldBtn.getStyleClass().add("buttonUp");
} }
public void setOneLineStatus(boolean status){
if (status)
statusLbl.setText(rb.getString("done_txt"));
else
statusLbl.setText(rb.getString("failure_txt"));
}
/**
* Save application settings on exit
* */
public void updatePreferencesOnExit(){
AppPreferences.getInstance().setNXDTSaveToLocation(saveToLocationLbl.getText());
}
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2018-2022 Dmitry Isaenko Copyright 2018-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -46,7 +46,7 @@ import nsusbloader.Utilities.patches.fs.FsPatchMaker;
import nsusbloader.Utilities.patches.loader.LoaderPatchMaker; import nsusbloader.Utilities.patches.loader.LoaderPatchMaker;
// TODO: CLI SUPPORT // TODO: CLI SUPPORT
public class PatchesController implements Initializable { public class PatchesController implements Initializable, ISubscriber {
@FXML @FXML
private VBox patchesToolPane; private VBox patchesToolPane;
@FXML @FXML
@ -237,9 +237,8 @@ public class PatchesController implements Initializable {
if (workThread != null && workThread.isAlive()) if (workThread != null && workThread.isAlive())
return; return;
statusLbl.setText("");
if (MediatorControl.getInstance().getTransferActive()) { if (MediatorControl.INSTANCE.getTransferActive()) {
ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"), ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"),
resourceBundle.getString("windowBodyPleaseStopOtherProcessFirst")); resourceBundle.getString("windowBodyPleaseStopOtherProcessFirst"));
return; return;
@ -261,9 +260,8 @@ public class PatchesController implements Initializable {
if (workThread != null && workThread.isAlive()) if (workThread != null && workThread.isAlive())
return; return;
statusLbl.setText("");
if (MediatorControl.getInstance().getTransferActive()) { if (MediatorControl.INSTANCE.getTransferActive()) {
ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"), ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"),
resourceBundle.getString("windowBodyPleaseStopOtherProcessFirst")); resourceBundle.getString("windowBodyPleaseStopOtherProcessFirst"));
return; return;
@ -285,9 +283,8 @@ public class PatchesController implements Initializable {
if (workThread != null && workThread.isAlive()) if (workThread != null && workThread.isAlive())
return; return;
statusLbl.setText("");
if (MediatorControl.getInstance().getTransferActive()) { if (MediatorControl.INSTANCE.getTransferActive()) {
ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"), ServiceWindow.getErrorNotification(resourceBundle.getString("windowTitleError"),
resourceBundle.getString("windowBodyPleaseStopOtherProcessFirst")); resourceBundle.getString("windowBodyPleaseStopOtherProcessFirst"));
return; return;
@ -306,18 +303,20 @@ public class PatchesController implements Initializable {
workThread.interrupt(); workThread.interrupt();
} }
public void notifyThreadStarted(boolean isActive, EModule type) { @Override
public void notify(EModule type, boolean isActive, Payload payload) {
if (! type.equals(EModule.PATCHES)) { if (! type.equals(EModule.PATCHES)) {
patchesToolPane.setDisable(isActive); patchesToolPane.setDisable(isActive);
return; return;
} }
statusLbl.setText(payload.getMessage());
convertRegionEs.getStyleClass().clear(); convertRegionEs.getStyleClass().clear();
makeFsBtn.setVisible(! isActive); makeFsBtn.setVisible(! isActive);
makeLoaderBtn.setVisible(! isActive); makeLoaderBtn.setVisible(! isActive);
if (isActive) { if (isActive) {
MediatorControl.getInstance().getContoller().logArea.clear();
convertRegionEs.getStyleClass().add("regionStop"); convertRegionEs.getStyleClass().add("regionStop");
makeEsBtn.setOnAction(e-> interruptProcessOfPatchMaking()); makeEsBtn.setOnAction(e-> interruptProcessOfPatchMaking());
@ -334,13 +333,6 @@ public class PatchesController implements Initializable {
makeEsBtn.getStyleClass().add("buttonUp"); 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(){ void updatePreferencesOnExit(){
AppPreferences.getInstance().setPatchesSaveToLocation(saveToLbl.getText()); AppPreferences.getInstance().setPatchesSaveToLocation(saveToLbl.getText());
if (locationKeysLbl.getText().isEmpty()) if (locationKeysLbl.getText().isEmpty())

View file

@ -0,0 +1,48 @@
/*
Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader.
NS-USBloader is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
NS-USBloader is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
*/
package nsusbloader.Controllers;
import nsusbloader.NSLDataTypes.EFileStatus;
import java.util.Collections;
import java.util.Map;
public class Payload {
private final String message;
private final Map<String, EFileStatus> statusMap;
public Payload(){
this("");
}
public Payload(String message){
this(message, Collections.emptyMap());
}
public Payload(String message, Map<String, EFileStatus> statusMap){
this.message = message;
this.statusMap = statusMap;
}
public String getMessage() {
return message;
}
public Map<String, EFileStatus> getStatusMap() {
return statusMap;
}
}

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -41,7 +41,7 @@ import java.io.File;
import java.net.URL; import java.net.URL;
import java.util.ResourceBundle; import java.util.ResourceBundle;
public class RcmController implements Initializable { public class RcmController implements Initializable, ISubscriber {
@FXML @FXML
private ToggleGroup rcmToggleGrp; private ToggleGroup rcmToggleGrp;
@ -68,12 +68,14 @@ public class RcmController implements Initializable {
@FXML @FXML
private Label statusLbl; private Label statusLbl;
private AppPreferences preferences;
private ResourceBundle rb; private ResourceBundle rb;
private String myRegexp; private String myRegexp;
@Override @Override
public void initialize(URL url, ResourceBundle resourceBundle) { public void initialize(URL url, ResourceBundle resourceBundle) {
this.rb = resourceBundle; this.rb = resourceBundle;
final AppPreferences preferences = AppPreferences.getInstance(); this.preferences = AppPreferences.getInstance();
rcmToggleGrp.selectToggle(pldrRadio1); rcmToggleGrp.selectToggle(pldrRadio1);
pldrRadio1.setOnAction(e -> statusLbl.setText("")); pldrRadio1.setOnAction(e -> statusLbl.setText(""));
@ -193,8 +195,7 @@ public class RcmController implements Initializable {
} }
private void smash(){ private void smash(){
statusLbl.setText(""); if (MediatorControl.INSTANCE.getTransferActive()) {
if (MediatorControl.getInstance().getTransferActive()) {
ServiceWindow.getErrorNotification(rb.getString("windowTitleError"), ServiceWindow.getErrorNotification(rb.getString("windowTitleError"),
rb.getString("windowBodyPleaseStopOtherProcessFirst")); rb.getString("windowBodyPleaseStopOtherProcessFirst"));
return; return;
@ -273,31 +274,28 @@ public class RcmController implements Initializable {
private void bntResetPayloader(ActionEvent event){ private void bntResetPayloader(ActionEvent event){
final Node btn = (Node)event.getSource(); final Node btn = (Node)event.getSource();
statusLbl.setText("");
switch (btn.getId()){ switch (btn.getId()){
case "resPldBtn1": case "resPldBtn1":
payloadFNameLbl1.setText(""); payloadFNameLbl1.setText("");
payloadFPathLbl1.setText(""); payloadFPathLbl1.setText("");
statusLbl.setText("");
break; break;
case "resPldBtn2": case "resPldBtn2":
payloadFNameLbl2.setText(""); payloadFNameLbl2.setText("");
payloadFPathLbl2.setText(""); payloadFPathLbl2.setText("");
statusLbl.setText("");
break; break;
case "resPldBtn3": case "resPldBtn3":
payloadFNameLbl3.setText(""); payloadFNameLbl3.setText("");
payloadFPathLbl3.setText(""); payloadFPathLbl3.setText("");
statusLbl.setText("");
break; break;
case "resPldBtn4": case "resPldBtn4":
payloadFNameLbl4.setText(""); payloadFNameLbl4.setText("");
payloadFPathLbl4.setText(""); payloadFPathLbl4.setText("");
statusLbl.setText("");
break; break;
case "resPldBtn5": case "resPldBtn5":
payloadFNameLbl5.setText(""); payloadFNameLbl5.setText("");
payloadFPathLbl5.setText(""); payloadFPathLbl5.setText("");
statusLbl.setText("");
} }
} }
@ -324,27 +322,20 @@ public class RcmController implements Initializable {
} }
} }
public void setOneLineStatus(boolean statusSuccess){ @Override
if (statusSuccess) public void notify(EModule type, boolean isActive, Payload payload) {
statusLbl.setText(rb.getString("done_txt")); rcmToolPane.setDisable(isActive);
else if (type.equals(EModule.RCM))
statusLbl.setText(rb.getString("failure_txt")); statusLbl.setText(payload.getMessage());
}
public void notifyThreadStarted(boolean isStart, EModule type){
rcmToolPane.setDisable(isStart);
if (type.equals(EModule.RCM) && isStart){
MediatorControl.getInstance().getContoller().logArea.clear();
}
} }
/** /**
* Save application settings on exit * Save application settings on exit
* */ * */
public void updatePreferencesOnExit(){ public void updatePreferencesOnExit(){
AppPreferences.getInstance().setRecentRcm(1, payloadFPathLbl1.getText()); preferences.setRecentRcm(1, payloadFPathLbl1.getText());
AppPreferences.getInstance().setRecentRcm(2, payloadFPathLbl2.getText()); preferences.setRecentRcm(2, payloadFPathLbl2.getText());
AppPreferences.getInstance().setRecentRcm(3, payloadFPathLbl3.getText()); preferences.setRecentRcm(3, payloadFPathLbl3.getText());
AppPreferences.getInstance().setRecentRcm(4, payloadFPathLbl4.getText()); preferences.setRecentRcm(4, payloadFPathLbl4.getText());
AppPreferences.getInstance().setRecentRcm(5, payloadFPathLbl5.getText()); preferences.setRecentRcm(5, payloadFPathLbl5.getText());
} }
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -55,9 +55,7 @@ public class SettingsBlockGenericController implements Initializable {
direcroriesChooserForRomsCB; direcroriesChooserForRomsCB;
@FXML @FXML
private Hyperlink newVersionHyperlink; private Hyperlink newVersionHyperlink;
private ResourceBundle resourceBundle; private ResourceBundle resourceBundle;
private HostServices hostServices; private HostServices hostServices;
@Override @Override
@ -68,8 +66,8 @@ public class SettingsBlockGenericController implements Initializable {
autoCheckForUpdatesCB.setSelected(preferences.getAutoCheckUpdates()); autoCheckForUpdatesCB.setSelected(preferences.getAutoCheckUpdates());
direcroriesChooserForRomsCB.setSelected(preferences.getDirectoriesChooserForRoms()); direcroriesChooserForRomsCB.setSelected(preferences.getDirectoriesChooserForRoms());
direcroriesChooserForRomsCB.setOnAction(actionEvent -> direcroriesChooserForRomsCB.setOnAction(actionEvent ->
MediatorControl.getInstance().getGamesController().updateFilesSelectorButtonBehaviour(direcroriesChooserForRomsCB.isSelected()) MediatorControl.INSTANCE.getGamesController().setFilesSelectorButtonBehaviour(direcroriesChooserForRomsCB.isSelected())
); );
Region btnSwitchImage = new Region(); Region btnSwitchImage = new Region();
btnSwitchImage.getStyleClass().add("regionUpdatesCheck"); btnSwitchImage.getStyleClass().add("regionUpdatesCheck");
@ -81,6 +79,7 @@ public class SettingsBlockGenericController implements Initializable {
languagesChB.setItems(settingsLanguagesSetup.getLanguages()); languagesChB.setItems(settingsLanguagesSetup.getLanguages());
languagesChB.getSelectionModel().select(settingsLanguagesSetup.getRecentLanguage()); languagesChB.getSelectionModel().select(settingsLanguagesSetup.getRecentLanguage());
hostServices = MediatorControl.INSTANCE.getHostServices();
newVersionHyperlink.setOnAction(e-> hostServices.showDocument(newVersionHyperlink.getText())); newVersionHyperlink.setOnAction(e-> hostServices.showDocument(newVersionHyperlink.getText()));
checkForUpdBtn.setOnAction(e->checkForUpdatesAction()); checkForUpdBtn.setOnAction(e->checkForUpdatesAction());
submitLanguageBtn.setOnAction(e->languageButtonAction()); submitLanguageBtn.setOnAction(e->languageButtonAction());
@ -149,8 +148,6 @@ public class SettingsBlockGenericController implements Initializable {
return direcroriesChooserForRomsCB.isSelected(); return direcroriesChooserForRomsCB.isSelected();
} }
protected void registerHostServices(HostServices hostServices){ this.hostServices = hostServices;}
void setNewVersionLink(String newVer){ void setNewVersionLink(String newVer){
newVersionHyperlink.setVisible(true); newVersionHyperlink.setVisible(true);
newVersionHyperlink.setText("https://github.com/developersu/ns-usbloader/releases/tag/"+newVer); newVersionHyperlink.setText("https://github.com/developersu/ns-usbloader/releases/tag/"+newVer);

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -31,7 +31,6 @@ import javafx.stage.FileChooser;
import nsusbloader.AppPreferences; import nsusbloader.AppPreferences;
import nsusbloader.FilesHelper; import nsusbloader.FilesHelper;
import nsusbloader.MediatorControl; import nsusbloader.MediatorControl;
import nsusbloader.ModelControllers.CancellableRunnable;
import nsusbloader.NSLDataTypes.EModule; import nsusbloader.NSLDataTypes.EModule;
import nsusbloader.ServiceWindow; import nsusbloader.ServiceWindow;
import nsusbloader.Utilities.splitmerge.SplitMergeTaskExecutor; import nsusbloader.Utilities.splitmerge.SplitMergeTaskExecutor;
@ -41,7 +40,7 @@ import java.net.URL;
import java.util.List; import java.util.List;
import java.util.ResourceBundle; import java.util.ResourceBundle;
public class SplitMergeController implements Initializable { public class SplitMergeController implements Initializable, ISubscriber {
@FXML @FXML
private ToggleGroup splitMergeTogGrp; private ToggleGroup splitMergeTogGrp;
@FXML @FXML
@ -147,13 +146,87 @@ public class SplitMergeController implements Initializable {
convertBtn.setOnAction(actionEvent -> setConvertBtnAction()); convertBtn.setOnAction(actionEvent -> setConvertBtnAction());
} }
public void notifyThreadStarted(boolean isStart, EModule type){ // todo: refactor: remove everything, place to separate container and just disable. /**
if (! type.equals(EModule.SPLIT_MERGE_TOOL)){ * It's button listener when convert-process in progress
smToolPane.setDisable(isStart); * */
private void stopBtnAction(){
if (smThread != null && smThread.isAlive()) {
smThread.interrupt();
}
}
/**
* It's button listener when convert-process NOT in progress
* */
private void setConvertBtnAction(){
if (MediatorControl.INSTANCE.getTransferActive()) {
ServiceWindow.getErrorNotification(
resourceBundle.getString("windowTitleError"),
resourceBundle.getString("windowBodyPleaseFinishTransfersFirst")
);
return; return;
} }
if (isStart){
MediatorControl.getInstance().getContoller().logArea.clear(); if (splitRad.isSelected())
smTask = new SplitMergeTaskExecutor(true, BlockListViewController.getItems(), saveToPathLbl.getText());
else
smTask = new SplitMergeTaskExecutor(false, BlockListViewController.getItems(), saveToPathLbl.getText());
smThread = new Thread(smTask);
smThread.setDaemon(true);
smThread.start();
}
/**
* Drag-n-drop support (dragOver consumer)
* */
@FXML
private void handleDragOver(DragEvent event){
if (event.getDragboard().hasFiles() && ! MediatorControl.INSTANCE.getTransferActive())
event.acceptTransferModes(TransferMode.ANY);
event.consume();
}
/**
* Drag-n-drop support (drop consumer)
* */
@FXML
private void handleDrop(DragEvent event) {
List<File> files = event.getDragboard().getFiles();
File firstFile = files.get(0);
if (firstFile.isDirectory())
mergeRad.fire();
else
splitRad.fire();
this.BlockListViewController.addAll(files);
event.setDropCompleted(true);
event.consume();
}
/**
* Save application settings on exit
* */
public void updatePreferencesOnExit(){
if (splitRad.isSelected())
AppPreferences.getInstance().setSplitMergeType(0);
else
AppPreferences.getInstance().setSplitMergeType(1);
AppPreferences.getInstance().setSplitMergeRecent(saveToPathLbl.getText());
}
@Override
public void notify(EModule type, boolean isActive, Payload payload) {
// todo: refactor: remove everything, place to separate container and just disable.
if (! type.equals(EModule.SPLIT_MERGE_TOOL)){
smToolPane.setDisable(isActive);
return;
}
statusLbl.setText(payload.getMessage());
if (isActive){
splitRad.setDisable(true); splitRad.setDisable(true);
mergeRad.setDisable(true); mergeRad.setDisable(true);
selectFileFolderBtn.setDisable(true); selectFileFolderBtn.setDisable(true);
@ -182,79 +255,4 @@ public class SplitMergeController implements Initializable {
else else
convertRegion.getStyleClass().add("regionOneToSplit"); convertRegion.getStyleClass().add("regionOneToSplit");
} }
/**
* It's button listener when convert-process in progress
* */
private void stopBtnAction(){
if (smThread != null && smThread.isAlive()) {
smThread.interrupt();
}
}
/**
* It's button listener when convert-process NOT in progress
* */
private void setConvertBtnAction(){
statusLbl.setText("");
if (MediatorControl.getInstance().getTransferActive()) {
ServiceWindow.getErrorNotification(
resourceBundle.getString("windowTitleError"),
resourceBundle.getString("windowBodyPleaseFinishTransfersFirst")
);
return;
}
if (splitRad.isSelected())
smTask = new SplitMergeTaskExecutor(true, BlockListViewController.getItems(), saveToPathLbl.getText());
else
smTask = new SplitMergeTaskExecutor(false, BlockListViewController.getItems(), saveToPathLbl.getText());
smThread = new Thread(smTask);
smThread.setDaemon(true);
smThread.start();
}
/**
* Drag-n-drop support (dragOver consumer)
* */
@FXML
private void handleDragOver(DragEvent event){
if (event.getDragboard().hasFiles() && ! MediatorControl.getInstance().getTransferActive())
event.acceptTransferModes(TransferMode.ANY);
event.consume();
}
/**
* Drag-n-drop support (drop consumer)
* */
@FXML
private void handleDrop(DragEvent event) {
List<File> files = event.getDragboard().getFiles();
File firstFile = files.get(0);
if (firstFile.isDirectory())
mergeRad.fire();
else
splitRad.fire();
this.BlockListViewController.addAll(files);
event.setDropCompleted(true);
event.consume();
}
public void setOneLineStatus(boolean status){
if (status)
statusLbl.setText(resourceBundle.getString("done_txt"));
else
statusLbl.setText(resourceBundle.getString("failure_txt"));
}
/**
* Save application settings on exit
* */
public void updatePreferencesOnExit(){
if (splitRad.isSelected())
AppPreferences.getInstance().setSplitMergeType(0);
else
AppPreferences.getInstance().setSplitMergeType(1);
AppPreferences.getInstance().setSplitMergeRecent(saveToPathLbl.getText());
}
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -18,50 +18,57 @@
*/ */
package nsusbloader; package nsusbloader;
import javafx.application.HostServices;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextArea;
import nsusbloader.Controllers.*; import nsusbloader.Controllers.*;
import nsusbloader.NSLDataTypes.EModule; import nsusbloader.NSLDataTypes.EModule;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.concurrent.atomic.AtomicBoolean;
public class MediatorControl { public class MediatorControl {
private final AtomicBoolean isTransferActive = new AtomicBoolean(false); // Overcoded just for sure public static final MediatorControl INSTANCE = new MediatorControl();
private NSLMainController mainController;
public static MediatorControl getInstance(){ private ResourceBundle resourceBundle;
return MediatorControlHold.INSTANCE; private TransfersPublisher transfersPublisher;
private HostServices hostServices;
private GamesController gamesController;
private SettingsController settingsController;
private TextArea logArea;
private ProgressBar progressBar;
private MediatorControl(){}
public void configure(ResourceBundle resourceBundle,
SettingsController settingsController,
TextArea logArea,
ProgressBar progressBar,
GamesController gamesController,
TransfersPublisher transfersPublisher) {
this.resourceBundle = resourceBundle;
this.settingsController = settingsController;
this.gamesController = gamesController;
this.logArea = logArea;
this.progressBar = progressBar;
this.transfersPublisher = transfersPublisher;
}
public void setHostServices(HostServices hostServices) {
this.hostServices = hostServices;
} }
private static class MediatorControlHold { public HostServices getHostServices() { return hostServices; }
private static final MediatorControl INSTANCE = new MediatorControl(); public ResourceBundle getResourceBundle(){ return resourceBundle; }
} public SettingsController getSettingsController() { return settingsController; }
public void setController(NSLMainController controller){ public GamesController getGamesController() { return gamesController; }
this.mainController = controller; public TextArea getLogArea() { return logArea; }
public ProgressBar getProgressBar() { return progressBar; }
public synchronized void setTransferActive(EModule appModuleType, boolean isActive, Payload payload) {
transfersPublisher.setTransferActive(appModuleType, isActive, payload);
} }
public NSLMainController getContoller(){ return mainController; } public synchronized boolean getTransferActive() {
public GamesController getGamesController(){ return mainController.getGamesCtrlr(); } return transfersPublisher.getTransferActive();
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();
}
public synchronized void setBgThreadActive(boolean isActive, EModule appModuleType) {
isTransferActive.set(isActive);
getGamesController().notifyThreadStarted(isActive, appModuleType);
getSplitMergeController().notifyThreadStarted(isActive, appModuleType);
getRcmController().notifyThreadStarted(isActive, appModuleType);
getNxdtController().notifyThreadStarted(isActive, appModuleType);
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

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -40,9 +40,13 @@ public class LogPrinterGui implements ILogPrinter {
LogPrinterGui(EModule whoIsAsking){ LogPrinterGui(EModule whoIsAsking){
this.msgQueue = new LinkedBlockingQueue<>(); this.msgQueue = new LinkedBlockingQueue<>();
this.progressQueue = new LinkedBlockingQueue<>(); this.progressQueue = new LinkedBlockingQueue<>();
this.statusMap = new HashMap<>(); this.statusMap = new HashMap<>();
this.oneLinerStatus = new AtomicBoolean(); this.oneLinerStatus = new AtomicBoolean();
this.msgConsumer = new MessagesConsumer(whoIsAsking, this.msgQueue, this.progressQueue, this.statusMap, this.oneLinerStatus); this.msgConsumer = new MessagesConsumer(whoIsAsking,
this.msgQueue,
this.progressQueue,
this.statusMap,
this.oneLinerStatus);
this.msgConsumer.start(); this.msgConsumer.start();
} }
/** /**

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -22,24 +22,26 @@ import javafx.animation.AnimationTimer;
import javafx.scene.control.ProgressBar; import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator; import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.TextArea; import javafx.scene.control.TextArea;
import nsusbloader.Controllers.NSTableViewController; import nsusbloader.Controllers.Payload;
import nsusbloader.MediatorControl; import nsusbloader.MediatorControl;
import nsusbloader.NSLDataTypes.EFileStatus; import nsusbloader.NSLDataTypes.EFileStatus;
import nsusbloader.NSLDataTypes.EModule; import nsusbloader.NSLDataTypes.EModule;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.ResourceBundle;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
public class MessagesConsumer extends AnimationTimer { public class MessagesConsumer extends AnimationTimer {
private final BlockingQueue<String> msgQueue; private static final MediatorControl mediator = MediatorControl.INSTANCE;
private final TextArea logsArea; private static final TextArea logsArea = mediator.getLogArea();
private static final ProgressBar progressBar = mediator.getProgressBar();;
private static final ResourceBundle resourceBundle = mediator.getResourceBundle();
private final BlockingQueue<String> msgQueue;
private final BlockingQueue<Double> progressQueue; private final BlockingQueue<Double> progressQueue;
private final ProgressBar progressBar;
private final HashMap<String, EFileStatus> statusMap; private final HashMap<String, EFileStatus> statusMap;
private final NSTableViewController tableViewController;
private final EModule appModuleType; private final EModule appModuleType;
private final AtomicBoolean oneLinerStatus; private final AtomicBoolean oneLinerStatus;
@ -53,22 +55,16 @@ public class MessagesConsumer extends AnimationTimer {
AtomicBoolean oneLinerStatus){ AtomicBoolean oneLinerStatus){
this.appModuleType = appModuleType; this.appModuleType = appModuleType;
this.isInterrupted = false; this.isInterrupted = false;
this.msgQueue = msgQueue; this.msgQueue = msgQueue;
this.logsArea = MediatorControl.getInstance().getContoller().logArea;
this.progressQueue = progressQueue; this.progressQueue = progressQueue;
this.progressBar = MediatorControl.getInstance().getContoller().progressBar;
this.statusMap = statusMap; this.statusMap = statusMap;
this.tableViewController = MediatorControl.getInstance().getGamesController().tableFilesListController;
this.oneLinerStatus = oneLinerStatus; this.oneLinerStatus = oneLinerStatus;
progressBar.setProgress(0.0); progressBar.setProgress(0.0);
progressBar.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS); progressBar.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
MediatorControl.getInstance().setBgThreadActive(true, appModuleType);
logsArea.clear();
mediator.setTransferActive(appModuleType, true, new Payload());
} }
@Override @Override
@ -89,32 +85,18 @@ public class MessagesConsumer extends AnimationTimer {
}); });
} }
if (isInterrupted) // It's safe 'cuz it's could't be interrupted while HashMap populating if (isInterrupted) // safe, could not be interrupted while HashMap populating
updateElementsAndStop(); updateElementsAndStop();
} }
private void updateElementsAndStop(){ private void updateElementsAndStop(){
MediatorControl.getInstance().setBgThreadActive(false, appModuleType); Payload payload = new Payload(
resourceBundle.getString(oneLinerStatus.get() ? "done_txt" : "failure_txt"),
statusMap);
mediator.setTransferActive(appModuleType, false, payload);
progressBar.setProgress(0.0); progressBar.setProgress(0.0);
if (statusMap.size() > 0){
for (String key : statusMap.keySet())
tableViewController.setFileStatus(key, statusMap.get(key));
}
switch (appModuleType){
case RCM:
MediatorControl.getInstance().getRcmController().setOneLineStatus(oneLinerStatus.get());
break;
case NXDT:
MediatorControl.getInstance().getNxdtController().setOneLineStatus(oneLinerStatus.get());
break;
case SPLIT_MERGE_TOOL:
MediatorControl.getInstance().getSplitMergeController().setOneLineStatus(oneLinerStatus.get());
break;
case PATCHES:
MediatorControl.getInstance().getPatchesController().setOneLineStatus(oneLinerStatus.get());
}
this.stop(); this.stop();
} }

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -68,14 +68,15 @@ public class NSLMain extends Application {
primaryStage.show(); primaryStage.show();
primaryStage.setOnCloseRequest(e->{ primaryStage.setOnCloseRequest(e->{
if (MediatorControl.getInstance().getTransferActive()) if (MediatorControl.INSTANCE.getTransferActive())
if(! ServiceWindow.getConfirmationWindow(rb.getString("windowTitleConfirmExit"), if(! ServiceWindow.getConfirmationWindow(rb.getString("windowTitleConfirmExit"),
rb.getString("windowBodyConfirmExit"))) rb.getString("windowBodyConfirmExit")))
e.consume(); e.consume();
}); });
NSLMainController controller = loader.getController(); NSLMainController controller = loader.getController();
controller.setHostServices(getHostServices()); MediatorControl.INSTANCE.setHostServices(getHostServices());
primaryStage.setOnHidden(e-> { primaryStage.setOnHidden(e-> {
AppPreferences.getInstance().setSceneHeight(mainScene.getHeight()); AppPreferences.getInstance().setSceneHeight(mainScene.getHeight());
AppPreferences.getInstance().setSceneWidth(mainScene.getWidth()); AppPreferences.getInstance().setSceneWidth(mainScene.getWidth());

View file

@ -0,0 +1,47 @@
/*
Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader.
NS-USBloader is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
NS-USBloader is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with NS-USBloader. If not, see <https://www.gnu.org/licenses/>.
*/
package nsusbloader;
import nsusbloader.Controllers.ISubscriber;
import nsusbloader.Controllers.Payload;
import nsusbloader.NSLDataTypes.EModule;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
public class TransfersPublisher {
private final AtomicBoolean isTransferActive = new AtomicBoolean(false);
private final List<ISubscriber> subscribers = new ArrayList<>();
public TransfersPublisher(ISubscriber... subscriber){
subscribers.addAll(Arrays.asList(subscriber));
}
public void setTransferActive(EModule appModuleType, boolean isActive, Payload payload) {
isTransferActive.set(isActive);
subscribers.forEach(s->s.notify(appModuleType, isActive, payload));
}
public boolean getTransferActive() {
return isTransferActive.get();
}
}

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2022 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -933,7 +933,7 @@ class GoldLeaf_010 extends TransferModule {
private boolean selectFile(){ private boolean selectFile(){
File selectedFile = CompletableFuture.supplyAsync(() -> { File selectedFile = CompletableFuture.supplyAsync(() -> {
FileChooser fChooser = new FileChooser(); FileChooser fChooser = new FileChooser();
fChooser.setTitle(MediatorControl.getInstance().getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION fChooser.setTitle(MediatorControl.INSTANCE.getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION
fChooser.setInitialDirectory(new File(System.getProperty("user.home")));// TODO: Consider fixing; not a priority. fChooser.setInitialDirectory(new File(System.getProperty("user.home")));// TODO: Consider fixing; not a priority.
fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*")); fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*"));
return fChooser.showOpenDialog(null); // Leave as is for now. return fChooser.showOpenDialog(null); // Leave as is for now.

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -918,7 +918,7 @@ class GoldLeaf_07 extends TransferModule {
private boolean selectFile(){ private boolean selectFile(){
File selectedFile = CompletableFuture.supplyAsync(() -> { File selectedFile = CompletableFuture.supplyAsync(() -> {
FileChooser fChooser = new FileChooser(); FileChooser fChooser = new FileChooser();
fChooser.setTitle(MediatorControl.getInstance().getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION fChooser.setTitle(MediatorControl.INSTANCE.getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION
fChooser.setInitialDirectory(new File(System.getProperty("user.home"))); // TODO: Consider fixing; not a prio. fChooser.setInitialDirectory(new File(System.getProperty("user.home"))); // TODO: Consider fixing; not a prio.
fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*")); fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*"));
return fChooser.showOpenDialog(null); // Leave as is for now. return fChooser.showOpenDialog(null); // Leave as is for now.

View file

@ -1,5 +1,5 @@
/* /*
Copyright 2019-2020 Dmitry Isaenko Copyright 2019-2024 Dmitry Isaenko
This file is part of NS-USBloader. This file is part of NS-USBloader.
@ -941,7 +941,7 @@ class GoldLeaf_08 extends TransferModule {
private boolean selectFile(){ private boolean selectFile(){
File selectedFile = CompletableFuture.supplyAsync(() -> { File selectedFile = CompletableFuture.supplyAsync(() -> {
FileChooser fChooser = new FileChooser(); FileChooser fChooser = new FileChooser();
fChooser.setTitle(MediatorControl.getInstance().getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION fChooser.setTitle(MediatorControl.INSTANCE.getResourceBundle().getString("btn_OpenFile")); // TODO: FIX BAD IMPLEMENTATION
fChooser.setInitialDirectory(new File(System.getProperty("user.home")));// TODO: Consider fixing; not a prio. fChooser.setInitialDirectory(new File(System.getProperty("user.home")));// TODO: Consider fixing; not a prio.
fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*")); fChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("*", "*"));
return fChooser.showOpenDialog(null); // Leave as is for now. return fChooser.showOpenDialog(null); // Leave as is for now.

View file

@ -169,7 +169,7 @@ public class UsbConnect {
"Double check that you have administrator privileges (you're 'root') or check 'udev' rules set for this user (linux only)!\n\n" + "Double check that you have administrator privileges (you're 'root') or check 'udev' rules set for this user (linux only)!\n\n" +
"Steps to set 'udev' rules:\n" + "Steps to set 'udev' rules:\n" +
"root # vim /etc/udev/rules.d/99-NS" + ((RCM_VID == VENDOR_ID) ? "RCM" : "") + ".rules\n" + "root # vim /etc/udev/rules.d/99-NS" + ((RCM_VID == VENDOR_ID) ? "RCM" : "") + ".rules\n" +
"SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", GROUP=\"plugdev\"\n" + "SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", MODE=\"0666\"\n" +
"root # udevadm control --reload-rules && udevadm trigger\n", UsbErrorCodes.getErrCode(returningValue), VENDOR_ID, PRODUCT_ID)); "root # udevadm control --reload-rules && udevadm trigger\n", UsbErrorCodes.getErrCode(returningValue), VENDOR_ID, PRODUCT_ID));
} }
else else

View file

@ -91,3 +91,7 @@ tabPatches_Btn_MakeAtmo=\uB85C\uB354 \uB9CC\uB4E4\uAE30 (Atmosphere)
tabPatches_Btn_MakeAll=\uBAA8\uB450 \uB9CC\uB4E4\uAE30 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_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. tabPatches_ServiceWindowMessageLoader='\uB85C\uB354' \uD328\uCE58\uB97C \uC0DD\uC131\uD558\uB824\uBA74 Atmosphere \uD3F4\uB354\uB97C \uC815\uC758\uD574\uC57C \uD569\uB2C8\uB2E4.
tab2_Btn_ApplicationFont=\uC751\uC6A9 \uD504\uB85C\uADF8\uB7A8 \uAE00\uAF34 \uBCC0\uACBD
btn_ResetToDefaults=\uC7AC\uC124\uC815
fontPreviewText=\uD14D\uC2A4\uD2B8 \uBBF8\uB9AC\uBCF4\uAE30
fontSize=\uAE00\uAF34 \uC0AC\uC774\uC988:

View file

@ -85,4 +85,20 @@ windowBodyFilesScanned=\u626B\u63CF\u6587\u4EF6: %25d\n\u88AB\u6DFB\u52A0: %25d
tab2_Lbl_AwooBlockTitle=awoo installer \u5B8C\u6210 tab2_Lbl_AwooBlockTitle=awoo installer \u5B8C\u6210
tabRcm_Lbl_Payload=Payload: 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=\u4fee\u6539\u7a0b\u5e8f\u5b57\u4f53
btn_ResetToDefaults=\u91cd\u7f6e
fontPreviewText=\u6587\u5b57\u9884\u89c8
fontSize=\u5b57\u53f7:

View file

@ -22,7 +22,7 @@ public class EsIntegrationTest {
pathToKeysFile = environment.getProdkeysLocation(); pathToKeysFile = environment.getProdkeysLocation();
saveTo = environment.getSaveToLocation() + File.separator + "ES_LPR"; saveTo = environment.getSaveToLocation() + File.separator + "ES_LPR";
pathToFirmwares = environment.getFirmwaresLocation(); pathToFirmwares = environment.getFirmwaresLocation();
pathToFirmware = pathToFirmware + File.separator + "Firmware 14.1.0"; pathToFirmware = environment.getFirmwaresLocation() + File.separator + "Firmware 17.0.0";
} }
@DisplayName("ES Integration validation - everything") @DisplayName("ES Integration validation - everything")

View file

@ -25,7 +25,7 @@ public class FsIntegrationTest {
pathToKeysFile = environment.getProdkeysLocation(); pathToKeysFile = environment.getProdkeysLocation();
saveTo = environment.getSaveToLocation() + File.separator + "FS_LPR"; saveTo = environment.getSaveToLocation() + File.separator + "FS_LPR";
pathToFirmwares = environment.getFirmwaresLocation(); pathToFirmwares = environment.getFirmwaresLocation();
pathToFirmware = pathToFirmware + File.separator + "Firmware 13.0.0"; pathToFirmware = environment.getFirmwaresLocation() + File.separator + "Firmware 17.0.0";
} }
@DisplayName("FS Integration validation - everything") @DisplayName("FS Integration validation - everything")